353 lines · plain
1; Test transactional-execution intrinsics.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s4 5declare i32 @llvm.s390.tbegin(ptr, i32)6declare i32 @llvm.s390.tbegin.nofloat(ptr, i32)7declare void @llvm.s390.tbeginc(ptr, i32)8declare i32 @llvm.s390.tend()9declare void @llvm.s390.tabort(i64)10declare void @llvm.s390.ntstg(i64, ptr)11declare i32 @llvm.s390.etnd()12declare void @llvm.s390.ppa.txassist(i32)13 14; TBEGIN.15define void @test_tbegin() {16; CHECK-LABEL: test_tbegin:17; CHECK-NOT: stmg18; CHECK: std %f8,19; CHECK: std %f9,20; CHECK: std %f10,21; CHECK: std %f11,22; CHECK: std %f12,23; CHECK: std %f13,24; CHECK: std %f14,25; CHECK: std %f15,26; CHECK: tbegin 0, 6529227; CHECK: ld %f8,28; CHECK: ld %f9,29; CHECK: ld %f10,30; CHECK: ld %f11,31; CHECK: ld %f12,32; CHECK: ld %f13,33; CHECK: ld %f14,34; CHECK: ld %f15,35; CHECK: br %r1436 call i32 @llvm.s390.tbegin(ptr null, i32 65292)37 ret void38}39 40; TBEGIN (nofloat).41define void @test_tbegin_nofloat1() {42; CHECK-LABEL: test_tbegin_nofloat1:43; CHECK-NOT: stmg44; CHECK-NOT: std45; CHECK: tbegin 0, 6529246; CHECK: br %r1447 call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 65292)48 ret void49}50 51; TBEGIN (nofloat) with integer CC return value.52define i32 @test_tbegin_nofloat2() {53; CHECK-LABEL: test_tbegin_nofloat2:54; CHECK-NOT: stmg55; CHECK-NOT: std56; CHECK: tbegin 0, 6529257; CHECK: ipm %r258; CHECK: srl %r2, 2859; CHECK: br %r1460 %res = call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 65292)61 ret i32 %res62}63 64; TBEGIN (nofloat) with implicit CC check.65define void @test_tbegin_nofloat3(ptr %ptr) {66; CHECK-LABEL: test_tbegin_nofloat3:67; CHECK-NOT: stmg68; CHECK-NOT: std69; CHECK: tbegin 0, 6529270; CHECK: bnhr %r1471; CHECK: mvhi 0(%r2), 072; CHECK: br %r1473 %res = call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 65292)74 %cmp = icmp eq i32 %res, 275 br i1 %cmp, label %if.then, label %if.end76 77if.then: ; preds = %entry78 store i32 0, ptr %ptr, align 479 br label %if.end80 81if.end: ; preds = %if.then, %entry82 ret void83}84 85; TBEGIN (nofloat) with dual CC use.86define i32 @test_tbegin_nofloat4(i32 %pad, ptr %ptr) {87; CHECK-LABEL: test_tbegin_nofloat4:88; CHECK-NOT: stmg89; CHECK-NOT: std90; CHECK: tbegin 0, 6529291; CHECK: ipm %r292; CHECK: srl %r2, 2893; CHECK: bnhr %r1494; CHECK: mvhi 0(%r3), 095; CHECK: br %r1496 %res = call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 65292)97 %cmp = icmp eq i32 %res, 298 br i1 %cmp, label %if.then, label %if.end99 100if.then: ; preds = %entry101 store i32 0, ptr %ptr, align 4102 br label %if.end103 104if.end: ; preds = %if.then, %entry105 ret i32 %res106}107 108; TBEGIN (nofloat) with register.109define void @test_tbegin_nofloat5(ptr %ptr) {110; CHECK-LABEL: test_tbegin_nofloat5:111; CHECK-NOT: stmg112; CHECK-NOT: std113; CHECK: tbegin 0(%r2), 65292114; CHECK: br %r14115 call i32 @llvm.s390.tbegin.nofloat(ptr %ptr, i32 65292)116 ret void117}118 119; TBEGIN (nofloat) with GRSM 0x0f00.120define void @test_tbegin_nofloat6() {121; CHECK-LABEL: test_tbegin_nofloat6:122; CHECK: stmg %r6, %r15,123; CHECK-NOT: std124; CHECK: tbegin 0, 3840125; CHECK: br %r14126 call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 3840)127 ret void128}129 130; TBEGIN (nofloat) with GRSM 0xf100.131define void @test_tbegin_nofloat7() {132; CHECK-LABEL: test_tbegin_nofloat7:133; CHECK: stmg %r8, %r15,134; CHECK-NOT: std135; CHECK: tbegin 0, 61696136; CHECK: br %r14137 call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 61696)138 ret void139}140 141; TBEGIN (nofloat) with GRSM 0xfe00 -- stack pointer added automatically.142define void @test_tbegin_nofloat8() {143; CHECK-LABEL: test_tbegin_nofloat8:144; CHECK-NOT: stmg145; CHECK-NOT: std146; CHECK: tbegin 0, 65280147; CHECK: br %r14148 call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 65024)149 ret void150}151 152; TBEGIN (nofloat) with GRSM 0xfb00 -- no frame pointer needed.153define void @test_tbegin_nofloat9() {154; CHECK-LABEL: test_tbegin_nofloat9:155; CHECK: stmg %r10, %r15,156; CHECK-NOT: std157; CHECK: tbegin 0, 64256158; CHECK: br %r14159 call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 64256)160 ret void161}162 163; TBEGIN (nofloat) with GRSM 0xfb00 -- frame pointer added automatically.164define void @test_tbegin_nofloat10(i64 %n) {165; CHECK-LABEL: test_tbegin_nofloat10:166; CHECK: stmg %r11, %r15,167; CHECK-NOT: std168; CHECK: tbegin 0, 65280169; CHECK: br %r14170 %buf = alloca i8, i64 %n171 call i32 @llvm.s390.tbegin.nofloat(ptr null, i32 64256)172 ret void173}174 175; TBEGINC.176define void @test_tbeginc() {177; CHECK-LABEL: test_tbeginc:178; CHECK-NOT: stmg179; CHECK-NOT: std180; CHECK: tbeginc 0, 65288181; CHECK: br %r14182 call void @llvm.s390.tbeginc(ptr null, i32 65288)183 ret void184}185 186; TEND with integer CC return value.187define i32 @test_tend1() {188; CHECK-LABEL: test_tend1:189; CHECK: tend190; CHECK: ipm %r2191; CHECK: srl %r2, 28192; CHECK: br %r14193 %res = call i32 @llvm.s390.tend()194 ret i32 %res195}196 197; TEND with implicit CC check.198define void @test_tend3(ptr %ptr) {199; CHECK-LABEL: test_tend3:200; CHECK: tend201; CHECK: ber %r14202; CHECK: mvhi 0(%r2), 0203; CHECK: br %r14204 %res = call i32 @llvm.s390.tend()205 %cmp = icmp eq i32 %res, 2206 br i1 %cmp, label %if.then, label %if.end207 208if.then: ; preds = %entry209 store i32 0, ptr %ptr, align 4210 br label %if.end211 212if.end: ; preds = %if.then, %entry213 ret void214}215 216; TEND with dual CC use.217define i32 @test_tend2(i32 %pad, ptr %ptr) {218; CHECK-LABEL: test_tend2:219; CHECK: tend220; CHECK: ipm %r2221; CHECK: srl %r2, 28222; CHECK: bnhr %r14223; CHECK: mvhi 0(%r3), 0224; CHECK: br %r14225 %res = call i32 @llvm.s390.tend()226 %cmp = icmp eq i32 %res, 2227 br i1 %cmp, label %if.then, label %if.end228 229if.then: ; preds = %entry230 store i32 0, ptr %ptr, align 4231 br label %if.end232 233if.end: ; preds = %if.then, %entry234 ret i32 %res235}236 237; TABORT with register only.238define void @test_tabort1(i64 %val) {239; CHECK-LABEL: test_tabort1:240; CHECK: tabort 0(%r2)241; CHECK: br %r14242 call void @llvm.s390.tabort(i64 %val)243 ret void244}245 246; TABORT with immediate only.247define void @test_tabort2(i64 %val) {248; CHECK-LABEL: test_tabort2:249; CHECK: tabort 1234250; CHECK: br %r14251 call void @llvm.s390.tabort(i64 1234)252 ret void253}254 255; TABORT with register + immediate.256define void @test_tabort3(i64 %val) {257; CHECK-LABEL: test_tabort3:258; CHECK: tabort 1234(%r2)259; CHECK: br %r14260 %sum = add i64 %val, 1234261 call void @llvm.s390.tabort(i64 %sum)262 ret void263}264 265; TABORT with out-of-range immediate.266define void @test_tabort4(i64 %val) {267; CHECK-LABEL: test_tabort4:268; CHECK: tabort 0({{%r[1-5]}})269; CHECK: br %r14270 call void @llvm.s390.tabort(i64 4096)271 ret void272}273 274; NTSTG with base pointer only.275define void @test_ntstg1(ptr %ptr, i64 %val) {276; CHECK-LABEL: test_ntstg1:277; CHECK: ntstg %r3, 0(%r2)278; CHECK: br %r14279 call void @llvm.s390.ntstg(i64 %val, ptr %ptr)280 ret void281}282 283; NTSTG with base and index.284; Check that VSTL doesn't allow an index.285define void @test_ntstg2(ptr %base, i64 %index, i64 %val) {286; CHECK-LABEL: test_ntstg2:287; CHECK: sllg [[REG:%r[1-5]]], %r3, 3288; CHECK: ntstg %r4, 0([[REG]],%r2)289; CHECK: br %r14290 %ptr = getelementptr i64, ptr %base, i64 %index291 call void @llvm.s390.ntstg(i64 %val, ptr %ptr)292 ret void293}294 295; NTSTG with the highest in-range displacement.296define void @test_ntstg3(ptr %base, i64 %val) {297; CHECK-LABEL: test_ntstg3:298; CHECK: ntstg %r3, 524280(%r2)299; CHECK: br %r14300 %ptr = getelementptr i64, ptr %base, i64 65535301 call void @llvm.s390.ntstg(i64 %val, ptr %ptr)302 ret void303}304 305; NTSTG with an out-of-range positive displacement.306define void @test_ntstg4(ptr %base, i64 %val) {307; CHECK-LABEL: test_ntstg4:308; CHECK: ntstg %r3, 0({{%r[1-5]}})309; CHECK: br %r14310 %ptr = getelementptr i64, ptr %base, i64 65536311 call void @llvm.s390.ntstg(i64 %val, ptr %ptr)312 ret void313}314 315; NTSTG with the lowest in-range displacement.316define void @test_ntstg5(ptr %base, i64 %val) {317; CHECK-LABEL: test_ntstg5:318; CHECK: ntstg %r3, -524288(%r2)319; CHECK: br %r14320 %ptr = getelementptr i64, ptr %base, i64 -65536321 call void @llvm.s390.ntstg(i64 %val, ptr %ptr)322 ret void323}324 325; NTSTG with an out-of-range negative displacement.326define void @test_ntstg6(ptr %base, i64 %val) {327; CHECK-LABEL: test_ntstg6:328; CHECK: ntstg %r3, 0({{%r[1-5]}})329; CHECK: br %r14330 %ptr = getelementptr i64, ptr %base, i64 -65537331 call void @llvm.s390.ntstg(i64 %val, ptr %ptr)332 ret void333}334 335; ETND.336define i32 @test_etnd() {337; CHECK-LABEL: test_etnd:338; CHECK: etnd %r2339; CHECK: br %r14340 %res = call i32 @llvm.s390.etnd()341 ret i32 %res342}343 344; PPA (Transaction-Abort Assist)345define void @test_ppa_txassist(i32 %val) {346; CHECK-LABEL: test_ppa_txassist:347; CHECK: ppa %r2, 0, 1348; CHECK: br %r14349 call void @llvm.s390.ppa.txassist(i32 %val)350 ret void351}352 353