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