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