1; Test 32-bit atomic minimum and maximum. Here we match the z10 versions, 2; which can't use LOCR. 3; 4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 5 6; Check signed minium. 7define i32 @f1(i32 %dummy, i32 *%src, i32 %b) { 8; CHECK-LABEL: f1: 9; CHECK: l %r2, 0(%r3) 10; CHECK: [[LOOP:\.[^:]*]]: 11; CHECK: lr [[NEW:%r[0-9]+]], %r2 12; CHECK: crjle %r2, %r4, [[KEEP:\..*]] 13; CHECK: lr [[NEW]], %r4 14; CHECK: cs %r2, [[NEW]], 0(%r3) 15; CHECK: ber %r14 16; CHECK: j [[LOOP]] 17 %res = atomicrmw min i32 *%src, i32 %b seq_cst 18 ret i32 %res 19} 20 21; Check signed maximum. 22define i32 @f2(i32 %dummy, i32 *%src, i32 %b) { 23; CHECK-LABEL: f2: 24; CHECK: l %r2, 0(%r3) 25; CHECK: [[LOOP:\.[^:]*]]: 26; CHECK: lr [[NEW:%r[0-9]+]], %r2 27; CHECK: crjhe %r2, %r4, [[KEEP:\..*]] 28; CHECK: lr [[NEW]], %r4 29; CHECK: cs %r2, [[NEW]], 0(%r3) 30; CHECK: ber %r14 31; CHECK: j [[LOOP]] 32 %res = atomicrmw max i32 *%src, i32 %b seq_cst 33 ret i32 %res 34} 35 36; Check unsigned minimum. 37define i32 @f3(i32 %dummy, i32 *%src, i32 %b) { 38; CHECK-LABEL: f3: 39; CHECK: l %r2, 0(%r3) 40; CHECK: [[LOOP:\.[^:]*]]: 41; CHECK: lr [[NEW:%r[0-9]+]], %r2 42; CHECK: clrjle %r2, %r4, [[KEEP:\..*]] 43; CHECK: lr [[NEW]], %r4 44; CHECK: cs %r2, [[NEW]], 0(%r3) 45; CHECK: ber %r14 46; CHECK: j [[LOOP]] 47 %res = atomicrmw umin i32 *%src, i32 %b seq_cst 48 ret i32 %res 49} 50 51; Check unsigned maximum. 52define i32 @f4(i32 %dummy, i32 *%src, i32 %b) { 53; CHECK-LABEL: f4: 54; CHECK: l %r2, 0(%r3) 55; CHECK: [[LOOP:\.[^:]*]]: 56; CHECK: lr [[NEW:%r[0-9]+]], %r2 57; CHECK: clrjhe %r2, %r4, [[KEEP:\..*]] 58; CHECK: lr [[NEW]], %r4 59; CHECK: cs %r2, [[NEW]], 0(%r3) 60; CHECK: ber %r14 61; CHECK: j [[LOOP]] 62 %res = atomicrmw umax i32 *%src, i32 %b seq_cst 63 ret i32 %res 64} 65 66; Check the high end of the aligned CS range. 67define i32 @f5(i32 %dummy, i32 *%src, i32 %b) { 68; CHECK-LABEL: f5: 69; CHECK: l %r2, 4092(%r3) 70; CHECK: cs %r2, {{%r[0-9]+}}, 4092(%r3) 71; CHECK: ber %r14 72 %ptr = getelementptr i32, i32 *%src, i64 1023 73 %res = atomicrmw min i32 *%ptr, i32 %b seq_cst 74 ret i32 %res 75} 76 77; Check the next word up, which requires CSY. 78define i32 @f6(i32 %dummy, i32 *%src, i32 %b) { 79; CHECK-LABEL: f6: 80; CHECK: ly %r2, 4096(%r3) 81; CHECK: csy %r2, {{%r[0-9]+}}, 4096(%r3) 82; CHECK: ber %r14 83 %ptr = getelementptr i32, i32 *%src, i64 1024 84 %res = atomicrmw min i32 *%ptr, i32 %b seq_cst 85 ret i32 %res 86} 87 88; Check the high end of the aligned CSY range. 89define i32 @f7(i32 %dummy, i32 *%src, i32 %b) { 90; CHECK-LABEL: f7: 91; CHECK: ly %r2, 524284(%r3) 92; CHECK: csy %r2, {{%r[0-9]+}}, 524284(%r3) 93; CHECK: ber %r14 94 %ptr = getelementptr i32, i32 *%src, i64 131071 95 %res = atomicrmw min i32 *%ptr, i32 %b seq_cst 96 ret i32 %res 97} 98 99; Check the next word up, which needs separate address logic. 100define i32 @f8(i32 %dummy, i32 *%src, i32 %b) { 101; CHECK-LABEL: f8: 102; CHECK: agfi %r3, 524288 103; CHECK: l %r2, 0(%r3) 104; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3) 105; CHECK: ber %r14 106 %ptr = getelementptr i32, i32 *%src, i64 131072 107 %res = atomicrmw min i32 *%ptr, i32 %b seq_cst 108 ret i32 %res 109} 110 111; Check the high end of the negative aligned CSY range. 112define i32 @f9(i32 %dummy, i32 *%src, i32 %b) { 113; CHECK-LABEL: f9: 114; CHECK: ly %r2, -4(%r3) 115; CHECK: csy %r2, {{%r[0-9]+}}, -4(%r3) 116; CHECK: ber %r14 117 %ptr = getelementptr i32, i32 *%src, i64 -1 118 %res = atomicrmw min i32 *%ptr, i32 %b seq_cst 119 ret i32 %res 120} 121 122; Check the low end of the CSY range. 123define i32 @f10(i32 %dummy, i32 *%src, i32 %b) { 124; CHECK-LABEL: f10: 125; CHECK: ly %r2, -524288(%r3) 126; CHECK: csy %r2, {{%r[0-9]+}}, -524288(%r3) 127; CHECK: ber %r14 128 %ptr = getelementptr i32, i32 *%src, i64 -131072 129 %res = atomicrmw min i32 *%ptr, i32 %b seq_cst 130 ret i32 %res 131} 132 133; Check the next word down, which needs separate address logic. 134define i32 @f11(i32 %dummy, i32 *%src, i32 %b) { 135; CHECK-LABEL: f11: 136; CHECK: agfi %r3, -524292 137; CHECK: l %r2, 0(%r3) 138; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3) 139; CHECK: ber %r14 140 %ptr = getelementptr i32, i32 *%src, i64 -131073 141 %res = atomicrmw min i32 *%ptr, i32 %b seq_cst 142 ret i32 %res 143} 144 145; Check that indexed addresses are not allowed. 146define i32 @f12(i32 %dummy, i64 %base, i64 %index, i32 %b) { 147; CHECK-LABEL: f12: 148; CHECK: agr %r3, %r4 149; CHECK: l %r2, 0(%r3) 150; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3) 151; CHECK: ber %r14 152 %add = add i64 %base, %index 153 %ptr = inttoptr i64 %add to i32 * 154 %res = atomicrmw min i32 *%ptr, i32 %b seq_cst 155 ret i32 %res 156} 157 158; Check that constants are handled. 159define i32 @f13(i32 %dummy, i32 *%ptr) { 160; CHECK-LABEL: f13: 161; CHECK: lhi [[LIMIT:%r[0-9]+]], 42 162; CHECK: l %r2, 0(%r3) 163; CHECK: [[LOOP:\.[^:]*]]: 164; CHECK: lr [[NEW:%r[0-9]+]], %r2 165; CHECK: crjle %r2, [[LIMIT]], [[KEEP:\..*]] 166; CHECK: lhi [[NEW]], 42 167; CHECK: cs %r2, [[NEW]], 0(%r3) 168; CHECK: ber %r14 169; CHECK: j [[LOOP]] 170 %res = atomicrmw min i32 *%ptr, i32 42 seq_cst 171 ret i32 %res 172} 173