175 lines · plain
1; Test 8-bit compare and swap.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK-MAIN4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s -check-prefix=CHECK-SHIFT5 6; Check compare and swap with a variable.7; - CHECK is for the main loop.8; - CHECK-SHIFT makes sure that the negated shift count used by the second9; RLL is set up correctly. The negation is independent of the NILL and L10; tested in CHECK. CHECK-SHIFT also checks that %r3 is not modified before11; being used in the RISBG (in contrast to things like atomic addition,12; which shift %r3 left so that %b is at the high end of the word).13define i8 @f1(i8 %dummy, ptr %src, i8 %cmp, i8 %swap) {14; CHECK-MAIN-LABEL: f1:15; CHECK-MAIN: risbg [[RISBG:%r[1-9]+]], %r3, 0, 189, 0{{$}}16; CHECK-MAIN-DAG: sll %r3, 317; CHECK-MAIN-DAG: l [[OLD:%r[0-9]+]], 0([[RISBG]])18; CHECK-MAIN-DAG: llcr %r4, %r419; CHECK-MAIN: [[LOOP:\.[^ ]*]]:20; CHECK-MAIN: rll %r2, [[OLD]], 8(%r3)21; CHECK-MAIN: risbg %r5, %r2, 32, 55, 022; CHECK-MAIN: llcr %r2, %r223; CHECK-MAIN: crjlh %r2, %r4, [[EXIT:\.[^ ]*]]24; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r5, -8({{%r[1-9]+}})25; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[RISBG]])26; CHECK-MAIN: jl [[LOOP]]27; CHECK-MAIN: [[EXIT]]:28; CHECK-MAIN-NOT: %r229; CHECK-MAIN: br %r1430;31; CHECK-SHIFT-LABEL: f1:32; CHECK-SHIFT: sll [[SHIFT:%r[1-9]+]], 333; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]34; CHECK-SHIFT: rll35; CHECK-SHIFT: rll {{%r[0-9]+}}, %r5, -8([[NEGSHIFT]])36 %pair = cmpxchg ptr %src, i8 %cmp, i8 %swap seq_cst seq_cst37 %res = extractvalue { i8, i1 } %pair, 038 ret i8 %res39}40 41; Check compare and swap with constants. We should force the constants into42; registers and use the sequence above.43define i8 @f2(ptr %src) {44; CHECK-LABEL: f2:45; CHECK: lhi [[CMP:%r[0-9]+]], 4246; CHECK: risbg [[CMP]], {{%r[0-9]+}}, 32, 55, 047; CHECK: risbg48; CHECK: br %r1449;50; CHECK-SHIFT-LABEL: f2:51; CHECK-SHIFT: lhi [[SWAP:%r[0-9]+]], 8852; CHECK-SHIFT: risbg [[SWAP]], {{%r[0-9]+}}, 32, 55, 053; CHECK-SHIFT: br %r1454 %pair = cmpxchg ptr %src, i8 42, i8 88 seq_cst seq_cst55 %res = extractvalue { i8, i1 } %pair, 056 ret i8 %res57}58 59; Check generating the comparison result.60define i32 @f3(i8 %dummy, ptr %src, i8 %cmp, i8 %swap) {61; CHECK-MAIN-LABEL: f3:62; CHECK-MAIN: risbg [[RISBG:%r[1-9]+]], %r3, 0, 189, 0{{$}}63; CHECK-MAIN-DAG: sll %r3, 364; CHECK-MAIN-DAG: l [[OLD:%r[0-9]+]], 0([[RISBG]])65; CHECK-MAIN-DAG: llcr %r2, %r466; CHECK-MAIN: [[LOOP:\.[^ ]*]]:67; CHECK-MAIN: rll [[TMP:%r[0-9]+]], [[OLD]], 8(%r3)68; CHECK-MAIN: risbg %r5, [[TMP]], 32, 55, 069; CHECK-MAIN: llcr [[TMP2:%r[0-9]+]], [[TMP]]70; CHECK-MAIN: cr [[TMP2]], %r271; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]]72; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r5, -8({{%r[1-9]+}})73; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[RISBG]])74; CHECK-MAIN: jl [[LOOP]]75; CHECK-MAIN: [[EXIT]]:76; CHECK-MAIN-NEXT: ipm %r277; CHECK-MAIN-NEXT: afi %r2, -26843545678; CHECK-MAIN-NEXT: srl %r2, 3179; CHECK-MAIN-NOT: %r280; CHECK-MAIN: br %r1481;82; CHECK-SHIFT-LABEL: f3:83; CHECK-SHIFT: sll [[SHIFT:%r[1-9]+]], 384; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], [[SHIFT]]85; CHECK-SHIFT: rll86; CHECK-SHIFT: rll {{%r[0-9]+}}, %r5, -8([[NEGSHIFT]])87 %pair = cmpxchg ptr %src, i8 %cmp, i8 %swap seq_cst seq_cst88 %val = extractvalue { i8, i1 } %pair, 189 %res = zext i1 %val to i3290 ret i32 %res91}92 93 94declare void @g()95 96; Check using the comparison result for a branch.97; CHECK-LABEL: f498; CHECK-MAIN-LABEL: f4:99; CHECK-MAIN: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}}100; CHECK-MAIN-DAG: sll %r2, 3101; CHECK-MAIN-DAG: l [[OLD:%r[0-9]+]], 0([[RISBG]])102; CHECK-MAIN-DAG: llcr %r3, %r3103; CHECK-MAIN: [[LOOP:\.[^ ]*]]:104; CHECK-MAIN: rll [[TMP:%r[0-9]+]], [[OLD]], 8(%r2)105; CHECK-MAIN: risbg %r4, [[TMP]], 32, 55, 0106; CHECK-MAIN: llcr [[TMP]], [[TMP]]107; CHECK-MAIN: cr [[TMP]], %r3108; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]]109; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r4, -8({{%r[1-9]+}})110; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[RISBG]])111; CHECK-MAIN: jl [[LOOP]]112; CHECK-MAIN: [[EXIT]]:113; CHECK-MAIN-NEXT: jlh [[LABEL:\.[^ ]*]]114; CHECK-MAIN: jg g115; CHECK-MAIN: [[LABEL]]:116; CHECK-MAIN: br %r14117;118; CHECK-SHIFT-LABEL: f4:119; CHECK-SHIFT: sll %r2, 3120; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], %r2121; CHECK-SHIFT: rll122; CHECK-SHIFT: rll {{%r[0-9]+}}, %r4, -8([[NEGSHIFT]])123define void @f4(ptr %src, i8 %cmp, i8 %swap) {124 %pair = cmpxchg ptr %src, i8 %cmp, i8 %swap seq_cst seq_cst125 %cond = extractvalue { i8, i1 } %pair, 1126 br i1 %cond, label %call, label %exit127 128call:129 tail call void @g()130 br label %exit131 132exit:133 ret void134}135 136; ... and the same with the inverted direction.137; CHECK-MAIN-LABEL: f5:138; CHECK-MAIN: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}}139; CHECK-MAIN-DAG: sll %r2, 3140; CHECK-MAIN-DAG: l [[OLD:%r[0-9]+]], 0([[RISBG]])141; CHECK-MAIN-DAG: llcr %r3, %r3142; CHECK-MAIN: [[LOOP:\.[^ ]*]]:143; CHECK-MAIN: rll [[TMP:%r[0-9]+]], [[OLD]], 8(%r2)144; CHECK-MAIN: risbg %r4, [[TMP]], 32, 55, 0145; CHECK-MAIN: llcr [[TMP]], [[TMP]]146; CHECK-MAIN: cr [[TMP]], %r3147; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]]148; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r4, -8({{%r[1-9]+}})149; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[RISBG]])150; CHECK-MAIN: jl [[LOOP]]151; CHECK-MAIN: [[EXIT]]:152; CHECK-MAIN-NEXT: jlh [[LABEL:\.[^ ]*]]153; CHECK-MAIN: br %r14154; CHECK-MAIN: [[LABEL]]:155; CHECK-MAIN: jg g156;157; CHECK-SHIFT-LABEL: f5:158; CHECK-SHIFT: sll %r2, 3159; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], %r2160; CHECK-SHIFT: rll161; CHECK-SHIFT: rll {{%r[0-9]+}}, %r4, -8([[NEGSHIFT]])162define void @f5(ptr %src, i8 %cmp, i8 %swap) {163 %pair = cmpxchg ptr %src, i8 %cmp, i8 %swap seq_cst seq_cst164 %cond = extractvalue { i8, i1 } %pair, 1165 br i1 %cond, label %exit, label %call166 167call:168 tail call void @g()169 br label %exit170 171exit:172 ret void173}174 175