1; Test 32-bit atomic exchange. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5; Check register exchange. 6define i32 @f1(i32 %dummy, i32 *%src, i32 %b) { 7; CHECK-LABEL: f1: 8; CHECK: l %r2, 0(%r3) 9; CHECK: [[LABEL:\.[^:]*]]: 10; CHECK: cs %r2, %r4, 0(%r3) 11; CHECK: jl [[LABEL]] 12; CHECK: br %r14 13 %res = atomicrmw xchg i32 *%src, i32 %b seq_cst 14 ret i32 %res 15} 16 17; Check the high end of the aligned CS range. 18define i32 @f2(i32 %dummy, i32 *%src, i32 %b) { 19; CHECK-LABEL: f2: 20; CHECK: l %r2, 4092(%r3) 21; CHECK: cs %r2, {{%r[0-9]+}}, 4092(%r3) 22; CHECK: br %r14 23 %ptr = getelementptr i32, i32 *%src, i64 1023 24 %res = atomicrmw xchg i32 *%ptr, i32 %b seq_cst 25 ret i32 %res 26} 27 28; Check the next word up, which requires CSY. 29define i32 @f3(i32 %dummy, i32 *%src, i32 %b) { 30; CHECK-LABEL: f3: 31; CHECK: ly %r2, 4096(%r3) 32; CHECK: csy %r2, {{%r[0-9]+}}, 4096(%r3) 33; CHECK: br %r14 34 %ptr = getelementptr i32, i32 *%src, i64 1024 35 %res = atomicrmw xchg i32 *%ptr, i32 %b seq_cst 36 ret i32 %res 37} 38 39; Check the high end of the aligned CSY range. 40define i32 @f4(i32 %dummy, i32 *%src, i32 %b) { 41; CHECK-LABEL: f4: 42; CHECK: ly %r2, 524284(%r3) 43; CHECK: csy %r2, {{%r[0-9]+}}, 524284(%r3) 44; CHECK: br %r14 45 %ptr = getelementptr i32, i32 *%src, i64 131071 46 %res = atomicrmw xchg i32 *%ptr, i32 %b seq_cst 47 ret i32 %res 48} 49 50; Check the next word up, which needs separate address logic. 51define i32 @f5(i32 %dummy, i32 *%src, i32 %b) { 52; CHECK-LABEL: f5: 53; CHECK: agfi %r3, 524288 54; CHECK: l %r2, 0(%r3) 55; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3) 56; CHECK: br %r14 57 %ptr = getelementptr i32, i32 *%src, i64 131072 58 %res = atomicrmw xchg i32 *%ptr, i32 %b seq_cst 59 ret i32 %res 60} 61 62; Check the high end of the negative aligned CSY range. 63define i32 @f6(i32 %dummy, i32 *%src, i32 %b) { 64; CHECK-LABEL: f6: 65; CHECK: ly %r2, -4(%r3) 66; CHECK: csy %r2, {{%r[0-9]+}}, -4(%r3) 67; CHECK: br %r14 68 %ptr = getelementptr i32, i32 *%src, i64 -1 69 %res = atomicrmw xchg i32 *%ptr, i32 %b seq_cst 70 ret i32 %res 71} 72 73; Check the low end of the CSY range. 74define i32 @f7(i32 %dummy, i32 *%src, i32 %b) { 75; CHECK-LABEL: f7: 76; CHECK: ly %r2, -524288(%r3) 77; CHECK: csy %r2, {{%r[0-9]+}}, -524288(%r3) 78; CHECK: br %r14 79 %ptr = getelementptr i32, i32 *%src, i64 -131072 80 %res = atomicrmw xchg i32 *%ptr, i32 %b seq_cst 81 ret i32 %res 82} 83 84; Check the next word down, which needs separate address logic. 85define i32 @f8(i32 %dummy, i32 *%src, i32 %b) { 86; CHECK-LABEL: f8: 87; CHECK: agfi %r3, -524292 88; CHECK: l %r2, 0(%r3) 89; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3) 90; CHECK: br %r14 91 %ptr = getelementptr i32, i32 *%src, i64 -131073 92 %res = atomicrmw xchg i32 *%ptr, i32 %b seq_cst 93 ret i32 %res 94} 95 96; Check that indexed addresses are not allowed. 97define i32 @f9(i32 %dummy, i64 %base, i64 %index, i32 %b) { 98; CHECK-LABEL: f9: 99; CHECK: agr %r3, %r4 100; CHECK: l %r2, 0(%r3) 101; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3) 102; CHECK: br %r14 103 %add = add i64 %base, %index 104 %ptr = inttoptr i64 %add to i32 * 105 %res = atomicrmw xchg i32 *%ptr, i32 %b seq_cst 106 ret i32 %res 107} 108 109; Check exchange of a constant. We should force it into a register and 110; use the sequence above. 111define i32 @f10(i32 %dummy, i32 *%src) { 112; CHECK-LABEL: f10: 113; CHECK-DAG: llill [[VALUE:%r[0-9+]]], 40000 114; CHECK-DAG: l %r2, 0(%r3) 115; CHECK: [[LABEL:\.[^:]*]]: 116; CHECK: cs %r2, [[VALUE]], 0(%r3) 117; CHECK: jl [[LABEL]] 118; CHECK: br %r14 119 %res = atomicrmw xchg i32 *%src, i32 40000 seq_cst 120 ret i32 %res 121} 122 123