1; RUN: llc < %s -mtriple=sparc -mcpu=v9 -verify-machineinstrs | FileCheck %s --check-prefixes=SPARC 2; RUN: llc < %s -mtriple=sparcv9 -verify-machineinstrs | FileCheck %s --check-prefixes=SPARC64 3 4; SPARC-LABEL: test_atomic_i8 5; SPARC: ldub [%o0] 6; SPARC: membar 7; SPARC: ldub [%o1] 8; SPARC: membar 9; SPARC: membar 10; SPARC: stb {{.+}}, [%o2] 11; SPARC64-LABEL: test_atomic_i8 12; SPARC64: ldub [%o0] 13; SPARC64: membar 14; SPARC64: ldub [%o1] 15; SPARC64: membar 16; SPARC64: membar 17; SPARC64: stb {{.+}}, [%o2] 18define i8 @test_atomic_i8(ptr %ptr1, ptr %ptr2, ptr %ptr3) { 19entry: 20 %0 = load atomic i8, ptr %ptr1 acquire, align 1 21 %1 = load atomic i8, ptr %ptr2 acquire, align 1 22 %2 = add i8 %0, %1 23 store atomic i8 %2, ptr %ptr3 release, align 1 24 ret i8 %2 25} 26 27; SPARC-LABEL: test_atomic_i16 28; SPARC: lduh [%o0] 29; SPARC: membar 30; SPARC: lduh [%o1] 31; SPARC: membar 32; SPARC: membar 33; SPARC: sth {{.+}}, [%o2] 34; SPARC64-LABEL: test_atomic_i16 35; SPARC64: lduh [%o0] 36; SPARC64: membar 37; SPARC64: lduh [%o1] 38; SPARC64: membar 39; SPARC64: membar 40; SPARC64: sth {{.+}}, [%o2] 41define i16 @test_atomic_i16(ptr %ptr1, ptr %ptr2, ptr %ptr3) { 42entry: 43 %0 = load atomic i16, ptr %ptr1 acquire, align 2 44 %1 = load atomic i16, ptr %ptr2 acquire, align 2 45 %2 = add i16 %0, %1 46 store atomic i16 %2, ptr %ptr3 release, align 2 47 ret i16 %2 48} 49 50; SPARC-LABEL: test_atomic_i32 51; SPARC: ld [%o0] 52; SPARC: membar 53; SPARC: ld [%o1] 54; SPARC: membar 55; SPARC: membar 56; SPARC: st {{.+}}, [%o2] 57; SPARC64-LABEL: test_atomic_i32 58; SPARC64: ld [%o0] 59; SPARC64: membar 60; SPARC64: ld [%o1] 61; SPARC64: membar 62; SPARC64: membar 63; SPARC64: st {{.+}}, [%o2] 64define i32 @test_atomic_i32(ptr %ptr1, ptr %ptr2, ptr %ptr3) { 65entry: 66 %0 = load atomic i32, ptr %ptr1 acquire, align 4 67 %1 = load atomic i32, ptr %ptr2 acquire, align 4 68 %2 = add i32 %0, %1 69 store atomic i32 %2, ptr %ptr3 release, align 4 70 ret i32 %2 71} 72 73;; TODO: the "move %icc" and related instructions are totally 74;; redundant here. There's something weird happening in optimization 75;; of the success value of cmpxchg. 76 77; SPARC-LABEL: test_cmpxchg_i8 78; SPARC: and %o1, -4, %o2 79; SPARC: mov 3, %o3 80; SPARC: andn %o3, %o1, %o1 81; SPARC: sll %o1, 3, %o1 82; SPARC: mov 255, %o3 83; SPARC: sll %o3, %o1, %o5 84; SPARC: xor %o5, -1, %o3 85; SPARC: mov 123, %o4 86; SPARC: ld [%o2], %g2 87; SPARC: sll %o4, %o1, %o4 88; SPARC: and %o0, 255, %o0 89; SPARC: sll %o0, %o1, %o0 90; SPARC: andn %g2, %o5, %o5 91; SPARC: [[LABEL1:\.L.*]]: 92; SPARC: or %o5, %o4, %g2 93; SPARC: or %o5, %o0, %g3 94; SPARC: cas [%o2], %g3, %g2 95; SPARC: mov %g0, %g4 96; SPARC: cmp %g2, %g3 97; SPARC: move %icc, 1, %g4 98; SPARC: cmp %g4, 0 99; SPARC: bne %icc, [[LABEL2:\.L.*]] 100; SPARC: nop 101; SPARC: and %g2, %o3, %g3 102; SPARC: cmp %o5, %g3 103; SPARC: bne %icc, [[LABEL1]] 104; SPARC: mov %g3, %o5 105; SPARC: [[LABEL2]]: 106; SPARC: retl 107; SPARC: srl %g2, %o1, %o0 108; SPARC64-LABEL: test_cmpxchg_i8 109; SPARC64: and %o1, -4, %o2 110; SPARC64: mov 3, %o3 111; SPARC64: andn %o3, %o1, %o1 112; SPARC64: sll %o1, 3, %o1 113; SPARC64: mov 255, %o3 114; SPARC64: sll %o3, %o1, %o5 115; SPARC64: xor %o5, -1, %o3 116; SPARC64: mov 123, %o4 117; SPARC64: ld [%o2], %g2 118; SPARC64: sll %o4, %o1, %o4 119; SPARC64: and %o0, 255, %o0 120; SPARC64: sll %o0, %o1, %o0 121; SPARC64: andn %g2, %o5, %o5 122; SPARC64: [[LABEL1:\.L.*]]: 123; SPARC64: or %o5, %o4, %g2 124; SPARC64: or %o5, %o0, %g3 125; SPARC64: cas [%o2], %g3, %g2 126; SPARC64: mov %g0, %g4 127; SPARC64: cmp %g2, %g3 128; SPARC64: move %icc, 1, %g4 129; SPARC64: cmp %g4, 0 130; SPARC64: bne %icc, [[LABEL2:\.L.*]] 131; SPARC64: nop 132; SPARC64: and %g2, %o3, %g3 133; SPARC64: cmp %o5, %g3 134; SPARC64: bne %icc, [[LABEL1]] 135; SPARC64: mov %g3, %o5 136; SPARC64: [[LABEL2]]: 137; SPARC64: retl 138; SPARC64: srl %g2, %o1, %o0 139define i8 @test_cmpxchg_i8(i8 %a, ptr %ptr) { 140entry: 141 %pair = cmpxchg ptr %ptr, i8 %a, i8 123 monotonic monotonic 142 %b = extractvalue { i8, i1 } %pair, 0 143 ret i8 %b 144} 145 146; SPARC-LABEL: test_cmpxchg_i16 147; SPARC: and %o1, -4, %o2 148; SPARC: and %o1, 3, %o1 149; SPARC: xor %o1, 2, %o1 150; SPARC: sll %o1, 3, %o1 151; SPARC: sethi 63, %o3 152; SPARC: or %o3, 1023, %o4 153; SPARC: sll %o4, %o1, %o5 154; SPARC: xor %o5, -1, %o3 155; SPARC: and %o0, %o4, %o4 156; SPARC: ld [%o2], %g2 157; SPARC: mov 123, %o0 158; SPARC: sll %o0, %o1, %o0 159; SPARC: sll %o4, %o1, %o4 160; SPARC: andn %g2, %o5, %o5 161; SPARC: [[LABEL1:\.L.*]]: 162; SPARC: or %o5, %o0, %g2 163; SPARC: or %o5, %o4, %g3 164; SPARC: cas [%o2], %g3, %g2 165; SPARC: mov %g0, %g4 166; SPARC: cmp %g2, %g3 167; SPARC: move %icc, 1, %g4 168; SPARC: cmp %g4, 0 169; SPARC: bne %icc, [[LABEL2:\.L.*]] 170; SPARC: nop 171; SPARC: and %g2, %o3, %g3 172; SPARC: cmp %o5, %g3 173; SPARC: bne %icc, [[LABEL1]] 174; SPARC: mov %g3, %o5 175; SPARC: [[LABEL2]]: 176; SPARC: retl 177; SPARC: srl %g2, %o1, %o0 178; SPARC64-LABEL: test_cmpxchg_i16 179; SPARC64: and %o1, -4, %o2 180; SPARC64: and %o1, 3, %o1 181; SPARC64: xor %o1, 2, %o1 182; SPARC64: sll %o1, 3, %o1 183; SPARC64: sethi 63, %o3 184; SPARC64: or %o3, 1023, %o4 185; SPARC64: sll %o4, %o1, %o5 186; SPARC64: xor %o5, -1, %o3 187; SPARC64: and %o0, %o4, %o4 188; SPARC64: ld [%o2], %g2 189; SPARC64: mov 123, %o0 190; SPARC64: sll %o0, %o1, %o0 191; SPARC64: sll %o4, %o1, %o4 192; SPARC64: andn %g2, %o5, %o5 193; SPARC64: [[LABEL1:\.L.*]]: 194; SPARC64: or %o5, %o0, %g2 195; SPARC64: or %o5, %o4, %g3 196; SPARC64: cas [%o2], %g3, %g2 197; SPARC64: mov %g0, %g4 198; SPARC64: cmp %g2, %g3 199; SPARC64: move %icc, 1, %g4 200; SPARC64: cmp %g4, 0 201; SPARC64: bne %icc, [[LABEL2:\.L.*]] 202; SPARC64: nop 203; SPARC64: and %g2, %o3, %g3 204; SPARC64: cmp %o5, %g3 205; SPARC64: bne %icc, [[LABEL1]] 206; SPARC64: mov %g3, %o5 207; SPARC64: [[LABEL2]]: 208; SPARC64: retl 209; SPARC64: srl %g2, %o1, %o0 210define i16 @test_cmpxchg_i16(i16 %a, ptr %ptr) { 211entry: 212 %pair = cmpxchg ptr %ptr, i16 %a, i16 123 monotonic monotonic 213 %b = extractvalue { i16, i1 } %pair, 0 214 ret i16 %b 215} 216 217; SPARC-LABEL: test_cmpxchg_i32 218; SPARC: mov 123, [[R:%[gilo][0-7]]] 219; SPARC: cas [%o1], %o0, [[R]] 220; SPARC64-LABEL: test_cmpxchg_i32 221; SPARC64: mov 123, [[R:%[gilo][0-7]]] 222; SPARC64: cas [%o1], %o0, [[R]] 223define i32 @test_cmpxchg_i32(i32 %a, ptr %ptr) { 224entry: 225 %pair = cmpxchg ptr %ptr, i32 %a, i32 123 monotonic monotonic 226 %b = extractvalue { i32, i1 } %pair, 0 227 ret i32 %b 228} 229 230; SPARC-LABEL: test_swap_i8 231; SPARC: mov 42, [[R:%[gilo][0-7]]] 232; SPARC: cas 233; SPARC64-LABEL: test_swap_i8 234; SPARC64: mov 42, [[R:%[gilo][0-7]]] 235; SPARC64: cas 236define i8 @test_swap_i8(i8 %a, ptr %ptr) { 237entry: 238 %b = atomicrmw xchg ptr %ptr, i8 42 monotonic 239 ret i8 %b 240} 241 242; SPARC-LABEL: test_swap_i16 243; SPARC: mov 42, [[R:%[gilo][0-7]]] 244; SPARC: cas 245; SPARC64-LABEL: test_swap_i16 246; SPARC64: mov 42, [[R:%[gilo][0-7]]] 247; SPARC64: cas 248define i16 @test_swap_i16(i16 %a, ptr %ptr) { 249entry: 250 %b = atomicrmw xchg ptr %ptr, i16 42 monotonic 251 ret i16 %b 252} 253 254; SPARC-LABEL: test_swap_i32 255; SPARC: mov 42, [[R:%[gilo][0-7]]] 256; SPARC: swap [%o1], [[R]] 257; SPARC64-LABEL: test_swap_i32 258; SPARC64: mov 42, [[R:%[gilo][0-7]]] 259; SPARC64: swap [%o1], [[R]] 260define i32 @test_swap_i32(i32 %a, ptr %ptr) { 261entry: 262 %b = atomicrmw xchg ptr %ptr, i32 42 monotonic 263 ret i32 %b 264} 265 266; SPARC-LABEL: test_load_sub_i8 267; SPARC: membar 268; SPARC: .L{{.*}}: 269; SPARC: sub 270; SPARC: cas [{{%[gilo][0-7]}}] 271; SPARC: membar 272; SPARC64-LABEL: test_load_sub_i8 273; SPARC64: membar 274; SPARC64: .L{{.*}}: 275; SPARC64: sub 276; SPARC64: cas [{{%[gilo][0-7]}}] 277; SPARC64: membar 278define zeroext i8 @test_load_sub_i8(ptr %p, i8 zeroext %v) { 279entry: 280 %0 = atomicrmw sub ptr %p, i8 %v seq_cst 281 ret i8 %0 282} 283 284; SPARC-LABEL: test_load_sub_i16 285; SPARC: membar 286; SPARC: .L{{.*}}: 287; SPARC: sub 288; SPARC: cas [{{%[gilo][0-7]}}] 289; SPARC: membar 290; SPARC64-LABEL: test_load_sub_i16 291; SPARC64: membar 292; SPARC64: .L{{.*}}: 293; SPARC64: sub 294; SPARC64: cas [{{%[gilo][0-7]}}] 295; SPARC64: membar 296define zeroext i16 @test_load_sub_i16(ptr %p, i16 zeroext %v) { 297entry: 298 %0 = atomicrmw sub ptr %p, i16 %v seq_cst 299 ret i16 %0 300} 301 302; SPARC-LABEL: test_load_add_i32 303; SPARC: membar 304; SPARC: mov [[U:%[gilo][0-7]]], [[V:%[gilo][0-7]]] 305; SPARC: add [[U:%[gilo][0-7]]], %o1, [[V2:%[gilo][0-7]]] 306; SPARC: cas [%o0], [[V]], [[V2]] 307; SPARC: membar 308; SPARC64-LABEL: test_load_add_i32 309; SPARC64: membar 310; SPARC64: mov [[U:%[gilo][0-7]]], [[V:%[gilo][0-7]]] 311; SPARC64: add [[U:%[gilo][0-7]]], %o1, [[V2:%[gilo][0-7]]] 312; SPARC64: cas [%o0], [[V]], [[V2]] 313; SPARC64: membar 314define zeroext i32 @test_load_add_i32(ptr %p, i32 zeroext %v) { 315entry: 316 %0 = atomicrmw add ptr %p, i32 %v seq_cst 317 ret i32 %0 318} 319 320; SPARC-LABEL: test_load_xor_32 321; SPARC: membar 322; SPARC: xor 323; SPARC: cas [%o0] 324; SPARC: membar 325; SPARC64-LABEL: test_load_xor_32 326; SPARC64: membar 327; SPARC64: xor 328; SPARC64: cas [%o0] 329; SPARC64: membar 330define zeroext i32 @test_load_xor_32(ptr %p, i32 zeroext %v) { 331entry: 332 %0 = atomicrmw xor ptr %p, i32 %v seq_cst 333 ret i32 %0 334} 335 336; SPARC-LABEL: test_load_and_32 337; SPARC: membar 338; SPARC: and 339; SPARC-NOT: xor 340; SPARC: cas [%o0] 341; SPARC: membar 342; SPARC64-LABEL: test_load_and_32 343; SPARC64: membar 344; SPARC64: and 345; SPARC64-NOT: xor 346; SPARC64: cas [%o0] 347; SPARC64: membar 348define zeroext i32 @test_load_and_32(ptr %p, i32 zeroext %v) { 349entry: 350 %0 = atomicrmw and ptr %p, i32 %v seq_cst 351 ret i32 %0 352} 353 354; SPARC-LABEL: test_load_nand_32 355; SPARC: membar 356; SPARC: and 357; SPARC: xor 358; SPARC: cas [%o0] 359; SPARC: membar 360; SPARC64-LABEL: test_load_nand_32 361; SPARC64: membar 362; SPARC64: and 363; SPARC64: xor 364; SPARC64: cas [%o0] 365; SPARC64: membar 366define zeroext i32 @test_load_nand_32(ptr %p, i32 zeroext %v) { 367entry: 368 %0 = atomicrmw nand ptr %p, i32 %v seq_cst 369 ret i32 %0 370} 371 372; SPARC-LABEL: test_load_umin_32 373; SPARC: membar 374; SPARC: cmp 375; SPARC: movleu %icc 376; SPARC: cas [%o0] 377; SPARC: membar 378; SPARC64-LABEL: test_load_umin_32 379; SPARC64: membar 380; SPARC64: cmp 381; SPARC64: movleu %icc 382; SPARC64: cas [%o0] 383; SPARC64: membar 384define zeroext i32 @test_load_umin_32(ptr %p, i32 zeroext %v) { 385entry: 386 %0 = atomicrmw umin ptr %p, i32 %v seq_cst 387 ret i32 %0 388} 389