1; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s 2 3;;; Test atomicrmw operations 4 5@c = common global i8 0, align 4 6@s = common global i16 0, align 4 7@i = common global i32 0, align 4 8@l = common global i64 0, align 4 9 10; Function Attrs: norecurse nounwind 11define signext i8 @test_atomic_fetch_add_1() { 12; CHECK-LABEL: test_atomic_fetch_add_1: 13; CHECK: # %bb.0: # %entry 14; CHECK-NEXT: fencem 3 15; CHECK-NEXT: lea %s0, c@lo 16; CHECK-NEXT: and %s0, %s0, (32)0 17; CHECK-NEXT: lea.sl %s0, c@hi(, %s0) 18; CHECK-NEXT: and %s0, -4, %s0 19; CHECK-NEXT: ldl.sx %s2, (, %s0) 20; CHECK-NEXT: lea %s1, -256 21; CHECK-NEXT: and %s1, %s1, (32)0 22; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 23; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 24; CHECK-NEXT: or %s3, 0, %s2 25; CHECK-NEXT: adds.w.sx %s2, 1, %s2 26; CHECK-NEXT: and %s2, %s2, (56)0 27; CHECK-NEXT: and %s4, %s3, %s1 28; CHECK-NEXT: or %s2, %s4, %s2 29; CHECK-NEXT: cas.w %s2, (%s0), %s3 30; CHECK-NEXT: brne.w %s2, %s3, .LBB{{[0-9]+}}_1 31; CHECK-NEXT: # %bb.2: # %atomicrmw.end 32; CHECK-NEXT: sll %s0, %s2, 56 33; CHECK-NEXT: sra.l %s0, %s0, 56 34; CHECK-NEXT: fencem 3 35; CHECK-NEXT: b.l.t (, %s10) 36entry: 37 %0 = atomicrmw add i8* @c, i8 1 seq_cst 38 ret i8 %0 39} 40 41; Function Attrs: norecurse nounwind 42define signext i16 @test_atomic_fetch_sub_2() { 43; CHECK-LABEL: test_atomic_fetch_sub_2: 44; CHECK: # %bb.0: # %entry 45; CHECK-NEXT: fencem 3 46; CHECK-NEXT: lea %s0, s@lo 47; CHECK-NEXT: and %s0, %s0, (32)0 48; CHECK-NEXT: lea.sl %s0, s@hi(, %s0) 49; CHECK-NEXT: and %s0, -4, %s0 50; CHECK-NEXT: ldl.sx %s2, (, %s0) 51; CHECK-NEXT: lea %s1, -65536 52; CHECK-NEXT: and %s1, %s1, (32)0 53; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 54; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 55; CHECK-NEXT: or %s3, 0, %s2 56; CHECK-NEXT: adds.w.sx %s2, -1, %s2 57; CHECK-NEXT: and %s2, %s2, (48)0 58; CHECK-NEXT: and %s4, %s3, %s1 59; CHECK-NEXT: or %s2, %s4, %s2 60; CHECK-NEXT: cas.w %s2, (%s0), %s3 61; CHECK-NEXT: brne.w %s2, %s3, .LBB{{[0-9]+}}_1 62; CHECK-NEXT: # %bb.2: # %atomicrmw.end 63; CHECK-NEXT: sll %s0, %s2, 48 64; CHECK-NEXT: sra.l %s0, %s0, 48 65; CHECK-NEXT: fencem 3 66; CHECK-NEXT: b.l.t (, %s10) 67entry: 68 %0 = atomicrmw sub i16* @s, i16 1 seq_cst 69 ret i16 %0 70} 71 72; Function Attrs: norecurse nounwind 73define signext i32 @test_atomic_fetch_and_4() { 74; CHECK-LABEL: test_atomic_fetch_and_4: 75; CHECK: # %bb.0: # %entry 76; CHECK-NEXT: fencem 3 77; CHECK-NEXT: lea %s0, i@lo 78; CHECK-NEXT: and %s0, %s0, (32)0 79; CHECK-NEXT: lea.sl %s0, i@hi(, %s0) 80; CHECK-NEXT: ldl.sx %s1, (, %s0) 81; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 82; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 83; CHECK-NEXT: or %s2, 0, %s1 84; CHECK-NEXT: and %s1, 1, %s2 85; CHECK-NEXT: cas.w %s1, (%s0), %s2 86; CHECK-NEXT: brne.w %s1, %s2, .LBB{{[0-9]+}}_1 87; CHECK-NEXT: # %bb.2: # %atomicrmw.end 88; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1 89; CHECK-NEXT: fencem 3 90; CHECK-NEXT: b.l.t (, %s10) 91entry: 92 %0 = atomicrmw and i32* @i, i32 1 seq_cst 93 ret i32 %0 94} 95; Function Attrs: norecurse nounwind 96define i64 @test_atomic_fetch_or_8() { 97; CHECK-LABEL: test_atomic_fetch_or_8: 98; CHECK: # %bb.0: # %entry 99; CHECK-NEXT: fencem 3 100; CHECK-NEXT: lea %s0, l@lo 101; CHECK-NEXT: and %s0, %s0, (32)0 102; CHECK-NEXT: lea.sl %s1, l@hi(, %s0) 103; CHECK-NEXT: ld %s0, (, %s1) 104; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 105; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 106; CHECK-NEXT: or %s2, 0, %s0 107; CHECK-NEXT: or %s0, 1, %s0 108; CHECK-NEXT: cas.l %s0, (%s1), %s2 109; CHECK-NEXT: brne.l %s0, %s2, .LBB{{[0-9]+}}_1 110; CHECK-NEXT: # %bb.2: # %atomicrmw.end 111; CHECK-NEXT: fencem 3 112; CHECK-NEXT: b.l.t (, %s10) 113entry: 114 %0 = atomicrmw or i64* @l, i64 1 seq_cst 115 ret i64 %0 116} 117 118; Function Attrs: norecurse nounwind 119define signext i8 @test_atomic_fetch_xor_1() { 120; CHECK-LABEL: test_atomic_fetch_xor_1: 121; CHECK: # %bb.0: # %entry 122; CHECK-NEXT: fencem 3 123; CHECK-NEXT: lea %s0, c@lo 124; CHECK-NEXT: and %s0, %s0, (32)0 125; CHECK-NEXT: lea.sl %s0, c@hi(, %s0) 126; CHECK-NEXT: and %s1, -4, %s0 127; CHECK-NEXT: ldl.sx %s0, (, %s1) 128; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 129; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 130; CHECK-NEXT: or %s2, 0, %s0 131; CHECK-NEXT: xor %s0, 1, %s2 132; CHECK-NEXT: cas.w %s0, (%s1), %s2 133; CHECK-NEXT: brne.w %s0, %s2, .LBB{{[0-9]+}}_1 134; CHECK-NEXT: # %bb.2: # %atomicrmw.end 135; CHECK-NEXT: sll %s0, %s0, 56 136; CHECK-NEXT: sra.l %s0, %s0, 56 137; CHECK-NEXT: fencem 3 138; CHECK-NEXT: b.l.t (, %s10) 139entry: 140 %0 = atomicrmw xor i8* @c, i8 1 seq_cst 141 ret i8 %0 142} 143 144; Function Attrs: norecurse nounwind 145define signext i16 @test_atomic_fetch_nand_2() { 146; CHECK-LABEL: test_atomic_fetch_nand_2: 147; CHECK: # %bb.0: # %entry 148; CHECK-NEXT: fencem 3 149; CHECK-NEXT: lea %s0, s@lo 150; CHECK-NEXT: and %s0, %s0, (32)0 151; CHECK-NEXT: lea.sl %s0, s@hi(, %s0) 152; CHECK-NEXT: and %s0, -4, %s0 153; CHECK-NEXT: ldl.sx %s2, (, %s0) 154; CHECK-NEXT: lea %s1, 65534 155; CHECK-NEXT: lea %s3, -65536 156; CHECK-NEXT: and %s3, %s3, (32)0 157; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 158; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 159; CHECK-NEXT: or %s4, 0, %s2 160; CHECK-NEXT: xor %s2, -1, %s4 161; CHECK-NEXT: or %s2, %s2, %s1 162; CHECK-NEXT: and %s2, %s2, (48)0 163; CHECK-NEXT: and %s5, %s4, %s3 164; CHECK-NEXT: or %s2, %s5, %s2 165; CHECK-NEXT: cas.w %s2, (%s0), %s4 166; CHECK-NEXT: brne.w %s2, %s4, .LBB{{[0-9]+}}_1 167; CHECK-NEXT: # %bb.2: # %atomicrmw.end 168; CHECK-NEXT: sll %s0, %s2, 48 169; CHECK-NEXT: sra.l %s0, %s0, 48 170; CHECK-NEXT: fencem 3 171; CHECK-NEXT: b.l.t (, %s10) 172entry: 173 %0 = atomicrmw nand i16* @s, i16 1 seq_cst 174 ret i16 %0 175} 176 177; Function Attrs: norecurse nounwind 178define signext i32 @test_atomic_fetch_max_4() { 179; CHECK-LABEL: test_atomic_fetch_max_4: 180; CHECK: # %bb.0: # %entry 181; CHECK-NEXT: fencem 3 182; CHECK-NEXT: lea %s0, i@lo 183; CHECK-NEXT: and %s0, %s0, (32)0 184; CHECK-NEXT: lea.sl %s1, i@hi(, %s0) 185; CHECK-NEXT: ldl.sx %s0, (, %s1) 186; CHECK-NEXT: or %s2, 1, (0)1 187; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 188; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 189; CHECK-NEXT: or %s3, 0, %s0 190; CHECK-NEXT: maxs.w.sx %s0, %s0, %s2 191; CHECK-NEXT: cas.w %s0, (%s1), %s3 192; CHECK-NEXT: brne.w %s0, %s3, .LBB{{[0-9]+}}_1 193; CHECK-NEXT: # %bb.2: # %atomicrmw.end 194; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 195; CHECK-NEXT: fencem 3 196; CHECK-NEXT: b.l.t (, %s10) 197entry: 198 %0 = atomicrmw max i32* @i, i32 1 seq_cst 199 ret i32 %0 200} 201 202; Function Attrs: norecurse nounwind 203define signext i32 @test_atomic_fetch_min_4() { 204; CHECK-LABEL: test_atomic_fetch_min_4: 205; CHECK: # %bb.0: # %entry 206; CHECK-NEXT: fencem 3 207; CHECK-NEXT: lea %s0, i@lo 208; CHECK-NEXT: and %s0, %s0, (32)0 209; CHECK-NEXT: lea.sl %s0, i@hi(, %s0) 210; CHECK-NEXT: ldl.sx %s1, (, %s0) 211; CHECK-NEXT: or %s2, 2, (0)1 212; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 213; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 214; CHECK-NEXT: or %s3, 0, %s1 215; CHECK-NEXT: cmps.w.sx %s4, %s1, %s2 216; CHECK-NEXT: or %s1, 1, (0)1 217; CHECK-NEXT: cmov.w.lt %s1, %s3, %s4 218; CHECK-NEXT: cas.w %s1, (%s0), %s3 219; CHECK-NEXT: brne.w %s1, %s3, .LBB{{[0-9]+}}_1 220; CHECK-NEXT: # %bb.2: # %atomicrmw.end 221; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1 222; CHECK-NEXT: fencem 3 223; CHECK-NEXT: b.l.t (, %s10) 224entry: 225 %0 = atomicrmw min i32* @i, i32 1 seq_cst 226 ret i32 %0 227} 228 229; Function Attrs: norecurse nounwind 230define signext i32 @test_atomic_fetch_umax_4() { 231; CHECK-LABEL: test_atomic_fetch_umax_4: 232; CHECK: # %bb.0: # %entry 233; CHECK-NEXT: fencem 3 234; CHECK-NEXT: lea %s0, i@lo 235; CHECK-NEXT: and %s0, %s0, (32)0 236; CHECK-NEXT: lea.sl %s0, i@hi(, %s0) 237; CHECK-NEXT: ldl.sx %s1, (, %s0) 238; CHECK-NEXT: or %s2, 1, (0)1 239; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 240; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 241; CHECK-NEXT: or %s3, 0, %s1 242; CHECK-NEXT: cmpu.w %s4, %s1, %s2 243; CHECK-NEXT: or %s1, 1, (0)1 244; CHECK-NEXT: cmov.w.gt %s1, %s3, %s4 245; CHECK-NEXT: cas.w %s1, (%s0), %s3 246; CHECK-NEXT: brne.w %s1, %s3, .LBB{{[0-9]+}}_1 247; CHECK-NEXT: # %bb.2: # %atomicrmw.end 248; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1 249; CHECK-NEXT: fencem 3 250; CHECK-NEXT: b.l.t (, %s10) 251entry: 252 %0 = atomicrmw umax i32* @i, i32 1 seq_cst 253 ret i32 %0 254} 255 256; Function Attrs: norecurse nounwind 257define signext i32 @test_atomic_fetch_umin_4() { 258; CHECK-LABEL: test_atomic_fetch_umin_4: 259; CHECK: # %bb.0: # %entry 260; CHECK-NEXT: fencem 3 261; CHECK-NEXT: lea %s0, i@lo 262; CHECK-NEXT: and %s0, %s0, (32)0 263; CHECK-NEXT: lea.sl %s0, i@hi(, %s0) 264; CHECK-NEXT: ldl.sx %s1, (, %s0) 265; CHECK-NEXT: or %s2, 2, (0)1 266; CHECK-NEXT: .LBB{{[0-9]+}}_1: # %atomicrmw.start 267; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 268; CHECK-NEXT: or %s3, 0, %s1 269; CHECK-NEXT: cmpu.w %s4, %s1, %s2 270; CHECK-NEXT: or %s1, 1, (0)1 271; CHECK-NEXT: cmov.w.lt %s1, %s3, %s4 272; CHECK-NEXT: cas.w %s1, (%s0), %s3 273; CHECK-NEXT: brne.w %s1, %s3, .LBB{{[0-9]+}}_1 274; CHECK-NEXT: # %bb.2: # %atomicrmw.end 275; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1 276; CHECK-NEXT: fencem 3 277; CHECK-NEXT: b.l.t (, %s10) 278entry: 279 %0 = atomicrmw umin i32* @i, i32 1 seq_cst 280 ret i32 %0 281} 282