brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · 8fa9ee0 Raw
310 lines · plain
1; Test 32-bit conditional stores that are presented as selects.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s4 5declare void @foo(ptr)6 7; Test the simple case, with the loaded value first.8define void @f1(ptr %ptr, i32 %alt, i32 %limit) {9; CHECK-LABEL: f1:10; CHECK-NOT: %r211; CHECK: blr %r1412; CHECK-NOT: %r213; CHECK: st %r3, 0(%r2)14; CHECK: br %r1415  %cond = icmp ult i32 %limit, 42016  %orig = load i32, ptr %ptr17  %res = select i1 %cond, i32 %orig, i32 %alt18  store i32 %res, ptr %ptr19  ret void20}21 22; ...and with the loaded value second23define void @f2(ptr %ptr, i32 %alt, i32 %limit) {24; CHECK-LABEL: f2:25; CHECK-NOT: %r226; CHECK: bher %r1427; CHECK-NOT: %r228; CHECK: st %r3, 0(%r2)29; CHECK: br %r1430  %cond = icmp ult i32 %limit, 42031  %orig = load i32, ptr %ptr32  %res = select i1 %cond, i32 %alt, i32 %orig33  store i32 %res, ptr %ptr34  ret void35}36 37; Test cases where the value is explicitly sign-extended to 64 bits, with the38; loaded value first.39define void @f3(ptr %ptr, i64 %alt, i32 %limit) {40; CHECK-LABEL: f3:41; CHECK-NOT: %r242; CHECK: blr %r1443; CHECK-NOT: %r244; CHECK: st %r3, 0(%r2)45; CHECK: br %r1446  %cond = icmp ult i32 %limit, 42047  %orig = load i32, ptr %ptr48  %ext = sext i32 %orig to i6449  %res = select i1 %cond, i64 %ext, i64 %alt50  %trunc = trunc i64 %res to i3251  store i32 %trunc, ptr %ptr52  ret void53}54 55; ...and with the loaded value second56define void @f4(ptr %ptr, i64 %alt, i32 %limit) {57; CHECK-LABEL: f4:58; CHECK-NOT: %r259; CHECK: bher %r1460; CHECK-NOT: %r261; CHECK: st %r3, 0(%r2)62; CHECK: br %r1463  %cond = icmp ult i32 %limit, 42064  %orig = load i32, ptr %ptr65  %ext = sext i32 %orig to i6466  %res = select i1 %cond, i64 %alt, i64 %ext67  %trunc = trunc i64 %res to i3268  store i32 %trunc, ptr %ptr69  ret void70}71 72; Test cases where the value is explicitly zero-extended to 32 bits, with the73; loaded value first.74define void @f5(ptr %ptr, i64 %alt, i32 %limit) {75; CHECK-LABEL: f5:76; CHECK-NOT: %r277; CHECK: blr %r1478; CHECK-NOT: %r279; CHECK: st %r3, 0(%r2)80; CHECK: br %r1481  %cond = icmp ult i32 %limit, 42082  %orig = load i32, ptr %ptr83  %ext = zext i32 %orig to i6484  %res = select i1 %cond, i64 %ext, i64 %alt85  %trunc = trunc i64 %res to i3286  store i32 %trunc, ptr %ptr87  ret void88}89 90; ...and with the loaded value second91define void @f6(ptr %ptr, i64 %alt, i32 %limit) {92; CHECK-LABEL: f6:93; CHECK-NOT: %r294; CHECK: bher %r1495; CHECK-NOT: %r296; CHECK: st %r3, 0(%r2)97; CHECK: br %r1498  %cond = icmp ult i32 %limit, 42099  %orig = load i32, ptr %ptr100  %ext = zext i32 %orig to i64101  %res = select i1 %cond, i64 %alt, i64 %ext102  %trunc = trunc i64 %res to i32103  store i32 %trunc, ptr %ptr104  ret void105}106 107; Check the high end of the aligned ST range.108define void @f7(ptr %base, i32 %alt, i32 %limit) {109; CHECK-LABEL: f7:110; CHECK-NOT: %r2111; CHECK: blr %r14112; CHECK-NOT: %r2113; CHECK: st %r3, 4092(%r2)114; CHECK: br %r14115  %ptr = getelementptr i32, ptr %base, i64 1023116  %cond = icmp ult i32 %limit, 420117  %orig = load i32, ptr %ptr118  %res = select i1 %cond, i32 %orig, i32 %alt119  store i32 %res, ptr %ptr120  ret void121}122 123; Check the next word up, which should use STY instead of ST.124define void @f8(ptr %base, i32 %alt, i32 %limit) {125; CHECK-LABEL: f8:126; CHECK-NOT: %r2127; CHECK: blr %r14128; CHECK-NOT: %r2129; CHECK: sty %r3, 4096(%r2)130; CHECK: br %r14131  %ptr = getelementptr i32, ptr %base, i64 1024132  %cond = icmp ult i32 %limit, 420133  %orig = load i32, ptr %ptr134  %res = select i1 %cond, i32 %orig, i32 %alt135  store i32 %res, ptr %ptr136  ret void137}138 139; Check the high end of the aligned STY range.140define void @f9(ptr %base, i32 %alt, i32 %limit) {141; CHECK-LABEL: f9:142; CHECK-NOT: %r2143; CHECK: blr %r14144; CHECK-NOT: %r2145; CHECK: sty %r3, 524284(%r2)146; CHECK: br %r14147  %ptr = getelementptr i32, ptr %base, i64 131071148  %cond = icmp ult i32 %limit, 420149  %orig = load i32, ptr %ptr150  %res = select i1 %cond, i32 %orig, i32 %alt151  store i32 %res, ptr %ptr152  ret void153}154 155; Check the next word up, which needs separate address logic.156; Other sequences besides this one would be OK.157define void @f10(ptr %base, i32 %alt, i32 %limit) {158; CHECK-LABEL: f10:159; CHECK-NOT: %r2160; CHECK: blr %r14161; CHECK-NOT: %r2162; CHECK: agfi %r2, 524288163; CHECK: st %r3, 0(%r2)164; CHECK: br %r14165  %ptr = getelementptr i32, ptr %base, i64 131072166  %cond = icmp ult i32 %limit, 420167  %orig = load i32, ptr %ptr168  %res = select i1 %cond, i32 %orig, i32 %alt169  store i32 %res, ptr %ptr170  ret void171}172 173; Check the low end of the STY range.174define void @f11(ptr %base, i32 %alt, i32 %limit) {175; CHECK-LABEL: f11:176; CHECK-NOT: %r2177; CHECK: blr %r14178; CHECK-NOT: %r2179; CHECK: sty %r3, -524288(%r2)180; CHECK: br %r14181  %ptr = getelementptr i32, ptr %base, i64 -131072182  %cond = icmp ult i32 %limit, 420183  %orig = load i32, ptr %ptr184  %res = select i1 %cond, i32 %orig, i32 %alt185  store i32 %res, ptr %ptr186  ret void187}188 189; Check the next word down, which needs separate address logic.190; Other sequences besides this one would be OK.191define void @f12(ptr %base, i32 %alt, i32 %limit) {192; CHECK-LABEL: f12:193; CHECK-NOT: %r2194; CHECK: blr %r14195; CHECK-NOT: %r2196; CHECK: agfi %r2, -524292197; CHECK: st %r3, 0(%r2)198; CHECK: br %r14199  %ptr = getelementptr i32, ptr %base, i64 -131073200  %cond = icmp ult i32 %limit, 420201  %orig = load i32, ptr %ptr202  %res = select i1 %cond, i32 %orig, i32 %alt203  store i32 %res, ptr %ptr204  ret void205}206 207; Check that STY allows an index.208define void @f13(i64 %base, i64 %index, i32 %alt, i32 %limit) {209; CHECK-LABEL: f13:210; CHECK-NOT: %r2211; CHECK: blr %r14212; CHECK-NOT: %r2213; CHECK: sty %r4, 4096(%r3,%r2)214; CHECK: br %r14215  %add1 = add i64 %base, %index216  %add2 = add i64 %add1, 4096217  %ptr = inttoptr i64 %add2 to ptr218  %cond = icmp ult i32 %limit, 420219  %orig = load i32, ptr %ptr220  %res = select i1 %cond, i32 %orig, i32 %alt221  store i32 %res, ptr %ptr222  ret void223}224 225; Check that volatile loads are not matched.226define void @f14(ptr %ptr, i32 %alt, i32 %limit) {227; CHECK-LABEL: f14:228; CHECK: l {{%r[0-5]}}, 0(%r2)229; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]230; CHECK: [[LABEL]]:231; CHECK: st {{%r[0-5]}}, 0(%r2)232; CHECK: br %r14233  %cond = icmp ult i32 %limit, 420234  %orig = load volatile i32, ptr %ptr235  %res = select i1 %cond, i32 %orig, i32 %alt236  store i32 %res, ptr %ptr237  ret void238}239 240; ...likewise stores.  In this case we should have a conditional load into %r3.241define void @f15(ptr %ptr, i32 %alt, i32 %limit) {242; CHECK-LABEL: f15:243; CHECK: jhe [[LABEL:[^ ]*]]244; CHECK: l %r3, 0(%r2)245; CHECK: [[LABEL]]:246; CHECK: st %r3, 0(%r2)247; CHECK: br %r14248  %cond = icmp ult i32 %limit, 420249  %orig = load i32, ptr %ptr250  %res = select i1 %cond, i32 %orig, i32 %alt251  store volatile i32 %res, ptr %ptr252  ret void253}254 255; Check that atomic loads are not matched.  The transformation is OK for256; the "unordered" case tested here, but since we don't try to handle atomic257; operations at all in this context, it seems better to assert that than258; to restrict the test to a stronger ordering.259define void @f16(ptr %ptr, i32 %alt, i32 %limit) {260; FIXME: should use a normal load instead of CS.261; CHECK-LABEL: f16:262; CHECK: l {{%r[0-5]}}, 0(%r2)263; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]264; CHECK: [[LABEL]]:265; CHECK: st {{%r[0-5]}}, 0(%r2)266; CHECK: br %r14267  %cond = icmp ult i32 %limit, 420268  %orig = load atomic i32, ptr %ptr unordered, align 4269  %res = select i1 %cond, i32 %orig, i32 %alt270  store i32 %res, ptr %ptr271  ret void272}273 274; ...likewise stores.275define void @f17(ptr %ptr, i32 %alt, i32 %limit) {276; FIXME: should use a normal store instead of CS.277; CHECK-LABEL: f17:278; CHECK: jhe [[LABEL:[^ ]*]]279; CHECK: l %r3, 0(%r2)280; CHECK: [[LABEL]]:281; CHECK: st %r3, 0(%r2)282; CHECK: br %r14283  %cond = icmp ult i32 %limit, 420284  %orig = load i32, ptr %ptr285  %res = select i1 %cond, i32 %orig, i32 %alt286  store atomic i32 %res, ptr %ptr unordered, align 4287  ret void288}289 290; Try a frame index base.291define void @f18(i32 %alt, i32 %limit) {292; CHECK-LABEL: f18:293; CHECK: brasl %r14, foo@PLT294; CHECK-NOT: %r15295; CHECK: jl [[LABEL:[^ ]*]]296; CHECK-NOT: %r15297; CHECK: st {{%r[0-9]+}}, {{[0-9]+}}(%r15)298; CHECK: [[LABEL]]:299; CHECK: brasl %r14, foo@PLT300; CHECK: br %r14301  %ptr = alloca i32302  call void @foo(ptr %ptr)303  %cond = icmp ult i32 %limit, 420304  %orig = load i32, ptr %ptr305  %res = select i1 %cond, i32 %orig, i32 %alt306  store i32 %res, ptr %ptr307  call void @foo(ptr %ptr)308  ret void309}310