161 lines · plain
1; Test 64-bit compare and swap.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5; Check CSG without a displacement.6define i64 @f1(i64 %cmp, i64 %swap, ptr %src) {7; CHECK-LABEL: f1:8; CHECK: csg %r2, %r3, 0(%r4)9; CHECK: br %r1410 %pairval = cmpxchg ptr %src, i64 %cmp, i64 %swap seq_cst seq_cst11 %val = extractvalue { i64, i1 } %pairval, 012 ret i64 %val13}14 15; Check the high end of the aligned CSG range.16define i64 @f2(i64 %cmp, i64 %swap, ptr %src) {17; CHECK-LABEL: f2:18; CHECK: csg %r2, %r3, 524280(%r4)19; CHECK: br %r1420 %ptr = getelementptr i64, ptr %src, i64 6553521 %pairval = cmpxchg ptr %ptr, i64 %cmp, i64 %swap seq_cst seq_cst22 %val = extractvalue { i64, i1 } %pairval, 023 ret i64 %val24}25 26; Check the next doubleword up, which needs separate address logic.27; Other sequences besides this one would be OK.28define i64 @f3(i64 %cmp, i64 %swap, ptr %src) {29; CHECK-LABEL: f3:30; CHECK: agfi %r4, 52428831; CHECK: csg %r2, %r3, 0(%r4)32; CHECK: br %r1433 %ptr = getelementptr i64, ptr %src, i64 6553634 %pairval = cmpxchg ptr %ptr, i64 %cmp, i64 %swap seq_cst seq_cst35 %val = extractvalue { i64, i1 } %pairval, 036 ret i64 %val37}38 39; Check the high end of the negative aligned CSG range.40define i64 @f4(i64 %cmp, i64 %swap, ptr %src) {41; CHECK-LABEL: f4:42; CHECK: csg %r2, %r3, -8(%r4)43; CHECK: br %r1444 %ptr = getelementptr i64, ptr %src, i64 -145 %pairval = cmpxchg ptr %ptr, i64 %cmp, i64 %swap seq_cst seq_cst46 %val = extractvalue { i64, i1 } %pairval, 047 ret i64 %val48}49 50; Check the low end of the CSG range.51define i64 @f5(i64 %cmp, i64 %swap, ptr %src) {52; CHECK-LABEL: f5:53; CHECK: csg %r2, %r3, -524288(%r4)54; CHECK: br %r1455 %ptr = getelementptr i64, ptr %src, i64 -6553656 %pairval = cmpxchg ptr %ptr, i64 %cmp, i64 %swap seq_cst seq_cst57 %val = extractvalue { i64, i1 } %pairval, 058 ret i64 %val59}60 61; Check the next doubleword down, which needs separate address logic.62; Other sequences besides this one would be OK.63define i64 @f6(i64 %cmp, i64 %swap, ptr %src) {64; CHECK-LABEL: f6:65; CHECK: agfi %r4, -52429666; CHECK: csg %r2, %r3, 0(%r4)67; CHECK: br %r1468 %ptr = getelementptr i64, ptr %src, i64 -6553769 %pairval = cmpxchg ptr %ptr, i64 %cmp, i64 %swap seq_cst seq_cst70 %val = extractvalue { i64, i1 } %pairval, 071 ret i64 %val72}73 74; Check that CSG does not allow an index.75define i64 @f7(i64 %cmp, i64 %swap, i64 %src, i64 %index) {76; CHECK-LABEL: f7:77; CHECK: agr %r4, %r578; CHECK: csg %r2, %r3, 0(%r4)79; CHECK: br %r1480 %add1 = add i64 %src, %index81 %ptr = inttoptr i64 %add1 to ptr82 %pairval = cmpxchg ptr %ptr, i64 %cmp, i64 %swap seq_cst seq_cst83 %val = extractvalue { i64, i1 } %pairval, 084 ret i64 %val85}86 87; Check that a constant %cmp value is loaded into a register first.88define i64 @f8(i64 %dummy, i64 %swap, ptr %ptr) {89; CHECK-LABEL: f8:90; CHECK: lghi %r2, 100191; CHECK: csg %r2, %r3, 0(%r4)92; CHECK: br %r1493 %pairval = cmpxchg ptr %ptr, i64 1001, i64 %swap seq_cst seq_cst94 %val = extractvalue { i64, i1 } %pairval, 095 ret i64 %val96}97 98; Check that a constant %swap value is loaded into a register first.99define i64 @f9(i64 %cmp, ptr %ptr) {100; CHECK-LABEL: f9:101; CHECK: lghi [[SWAP:%r[0-9]+]], 1002102; CHECK: csg %r2, [[SWAP]], 0(%r3)103; CHECK: br %r14104 %pairval = cmpxchg ptr %ptr, i64 %cmp, i64 1002 seq_cst seq_cst105 %val = extractvalue { i64, i1 } %pairval, 0106 ret i64 %val107}108 109; Check generating the comparison result.110; CHECK-LABEL: f10111; CHECK: csg %r2, %r3, 0(%r4)112; CHECK-NEXT: ipm %r2113; CHECK-NEXT: afi %r2, -268435456114; CHECK-NEXT: srl %r2, 31115; CHECK: br %r14116define i32 @f10(i64 %cmp, i64 %swap, ptr %src) {117 %pairval = cmpxchg ptr %src, i64 %cmp, i64 %swap seq_cst seq_cst118 %val = extractvalue { i64, i1 } %pairval, 1119 %res = zext i1 %val to i32120 ret i32 %res121}122 123declare void @g()124 125; Check using the comparison result for a branch.126; CHECK-LABEL: f11127; CHECK: csg %r2, %r3, 0(%r4)128; CHECK-NEXT: jge g129; CHECK: br %r14130define void @f11(i64 %cmp, i64 %swap, ptr %src) {131 %pairval = cmpxchg ptr %src, i64 %cmp, i64 %swap seq_cst seq_cst132 %cond = extractvalue { i64, i1 } %pairval, 1133 br i1 %cond, label %call, label %exit134 135call:136 tail call void @g()137 br label %exit138 139exit:140 ret void141}142 143; ... and the same with the inverted direction.144; CHECK-LABEL: f12145; CHECK: csg %r2, %r3, 0(%r4)146; CHECK-NEXT: jgl g147; CHECK: br %r14148define void @f12(i64 %cmp, i64 %swap, ptr %src) {149 %pairval = cmpxchg ptr %src, i64 %cmp, i64 %swap seq_cst seq_cst150 %cond = extractvalue { i64, i1 } %pairval, 1151 br i1 %cond, label %exit, label %call152 153call:154 tail call void @g()155 br label %exit156 157exit:158 ret void159}160 161