brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.8 KiB · c5a2a87 Raw
381 lines · plain
1; Test 8-bit conditional stores that are presented as selects.  The volatile2; tests require z10, which use a branch instead of a LOCR.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s5 6declare void @foo(ptr)7 8; Test the simple case, with the loaded value first.9define void @f1(ptr %ptr, i8 %alt, i32 %limit) {10; CHECK-LABEL: f1:11; CHECK-NOT: %r212; CHECK: blr %r1413; CHECK-NOT: %r214; CHECK: stc %r3, 0(%r2)15; CHECK: br %r1416  %cond = icmp ult i32 %limit, 42017  %orig = load i8, ptr %ptr18  %res = select i1 %cond, i8 %orig, i8 %alt19  store i8 %res, ptr %ptr20  ret void21}22 23; ...and with the loaded value second24define void @f2(ptr %ptr, i8 %alt, i32 %limit) {25; CHECK-LABEL: f2:26; CHECK-NOT: %r227; CHECK: bher %r1428; CHECK-NOT: %r229; CHECK: stc %r3, 0(%r2)30; CHECK: br %r1431  %cond = icmp ult i32 %limit, 42032  %orig = load i8, ptr %ptr33  %res = select i1 %cond, i8 %alt, i8 %orig34  store i8 %res, ptr %ptr35  ret void36}37 38; Test cases where the value is explicitly sign-extended to 32 bits, with the39; loaded value first.40define void @f3(ptr %ptr, i32 %alt, i32 %limit) {41; CHECK-LABEL: f3:42; CHECK-NOT: %r243; CHECK: blr %r1444; CHECK-NOT: %r245; CHECK: stc %r3, 0(%r2)46; CHECK: br %r1447  %cond = icmp ult i32 %limit, 42048  %orig = load i8, ptr %ptr49  %ext = sext i8 %orig to i3250  %res = select i1 %cond, i32 %ext, i32 %alt51  %trunc = trunc i32 %res to i852  store i8 %trunc, ptr %ptr53  ret void54}55 56; ...and with the loaded value second57define void @f4(ptr %ptr, i32 %alt, i32 %limit) {58; CHECK-LABEL: f4:59; CHECK-NOT: %r260; CHECK: bher %r1461; CHECK-NOT: %r262; CHECK: stc %r3, 0(%r2)63; CHECK: br %r1464  %cond = icmp ult i32 %limit, 42065  %orig = load i8, ptr %ptr66  %ext = sext i8 %orig to i3267  %res = select i1 %cond, i32 %alt, i32 %ext68  %trunc = trunc i32 %res to i869  store i8 %trunc, ptr %ptr70  ret void71}72 73; Test cases where the value is explicitly zero-extended to 32 bits, with the74; loaded value first.75define void @f5(ptr %ptr, i32 %alt, i32 %limit) {76; CHECK-LABEL: f5:77; CHECK-NOT: %r278; CHECK: blr %r1479; CHECK-NOT: %r280; CHECK: stc %r3, 0(%r2)81; CHECK: br %r1482  %cond = icmp ult i32 %limit, 42083  %orig = load i8, ptr %ptr84  %ext = zext i8 %orig to i3285  %res = select i1 %cond, i32 %ext, i32 %alt86  %trunc = trunc i32 %res to i887  store i8 %trunc, ptr %ptr88  ret void89}90 91; ...and with the loaded value second92define void @f6(ptr %ptr, i32 %alt, i32 %limit) {93; CHECK-LABEL: f6:94; CHECK-NOT: %r295; CHECK: bher %r1496; CHECK-NOT: %r297; CHECK: stc %r3, 0(%r2)98; CHECK: br %r1499  %cond = icmp ult i32 %limit, 420100  %orig = load i8, ptr %ptr101  %ext = zext i8 %orig to i32102  %res = select i1 %cond, i32 %alt, i32 %ext103  %trunc = trunc i32 %res to i8104  store i8 %trunc, ptr %ptr105  ret void106}107 108; Test cases where the value is explicitly sign-extended to 64 bits, with the109; loaded value first.110define void @f7(ptr %ptr, i64 %alt, i32 %limit) {111; CHECK-LABEL: f7:112; CHECK-NOT: %r2113; CHECK: blr %r14114; CHECK-NOT: %r2115; CHECK: stc %r3, 0(%r2)116; CHECK: br %r14117  %cond = icmp ult i32 %limit, 420118  %orig = load i8, ptr %ptr119  %ext = sext i8 %orig to i64120  %res = select i1 %cond, i64 %ext, i64 %alt121  %trunc = trunc i64 %res to i8122  store i8 %trunc, ptr %ptr123  ret void124}125 126; ...and with the loaded value second127define void @f8(ptr %ptr, i64 %alt, i32 %limit) {128; CHECK-LABEL: f8:129; CHECK-NOT: %r2130; CHECK: bher %r14131; CHECK-NOT: %r2132; CHECK: stc %r3, 0(%r2)133; CHECK: br %r14134  %cond = icmp ult i32 %limit, 420135  %orig = load i8, ptr %ptr136  %ext = sext i8 %orig to i64137  %res = select i1 %cond, i64 %alt, i64 %ext138  %trunc = trunc i64 %res to i8139  store i8 %trunc, ptr %ptr140  ret void141}142 143; Test cases where the value is explicitly zero-extended to 64 bits, with the144; loaded value first.145define void @f9(ptr %ptr, i64 %alt, i32 %limit) {146; CHECK-LABEL: f9:147; CHECK-NOT: %r2148; CHECK: blr %r14149; CHECK-NOT: %r2150; CHECK: stc %r3, 0(%r2)151; CHECK: br %r14152  %cond = icmp ult i32 %limit, 420153  %orig = load i8, ptr %ptr154  %ext = zext i8 %orig to i64155  %res = select i1 %cond, i64 %ext, i64 %alt156  %trunc = trunc i64 %res to i8157  store i8 %trunc, ptr %ptr158  ret void159}160 161; ...and with the loaded value second162define void @f10(ptr %ptr, i64 %alt, i32 %limit) {163; CHECK-LABEL: f10:164; CHECK-NOT: %r2165; CHECK: bher %r14166; CHECK-NOT: %r2167; CHECK: stc %r3, 0(%r2)168; CHECK: br %r14169  %cond = icmp ult i32 %limit, 420170  %orig = load i8, ptr %ptr171  %ext = zext i8 %orig to i64172  %res = select i1 %cond, i64 %alt, i64 %ext173  %trunc = trunc i64 %res to i8174  store i8 %trunc, ptr %ptr175  ret void176}177 178; Check the high end of the STC range.179define void @f11(ptr %base, i8 %alt, i32 %limit) {180; CHECK-LABEL: f11:181; CHECK-NOT: %r2182; CHECK: blr %r14183; CHECK-NOT: %r2184; CHECK: stc %r3, 4095(%r2)185; CHECK: br %r14186  %ptr = getelementptr i8, ptr %base, i64 4095187  %cond = icmp ult i32 %limit, 420188  %orig = load i8, ptr %ptr189  %res = select i1 %cond, i8 %orig, i8 %alt190  store i8 %res, ptr %ptr191  ret void192}193 194; Check the next byte up, which should use STCY instead of STC.195define void @f12(ptr %base, i8 %alt, i32 %limit) {196; CHECK-LABEL: f12:197; CHECK-NOT: %r2198; CHECK: blr %r14199; CHECK-NOT: %r2200; CHECK: stcy %r3, 4096(%r2)201; CHECK: br %r14202  %ptr = getelementptr i8, ptr %base, i64 4096203  %cond = icmp ult i32 %limit, 420204  %orig = load i8, ptr %ptr205  %res = select i1 %cond, i8 %orig, i8 %alt206  store i8 %res, ptr %ptr207  ret void208}209 210; Check the high end of the STCY range.211define void @f13(ptr %base, i8 %alt, i32 %limit) {212; CHECK-LABEL: f13:213; CHECK-NOT: %r2214; CHECK: blr %r14215; CHECK-NOT: %r2216; CHECK: stcy %r3, 524287(%r2)217; CHECK: br %r14218  %ptr = getelementptr i8, ptr %base, i64 524287219  %cond = icmp ult i32 %limit, 420220  %orig = load i8, ptr %ptr221  %res = select i1 %cond, i8 %orig, i8 %alt222  store i8 %res, ptr %ptr223  ret void224}225 226; Check the next byte up, which needs separate address logic.227; Other sequences besides this one would be OK.228define void @f14(ptr %base, i8 %alt, i32 %limit) {229; CHECK-LABEL: f14:230; CHECK-NOT: %r2231; CHECK: blr %r14232; CHECK-NOT: %r2233; CHECK: agfi %r2, 524288234; CHECK: stc %r3, 0(%r2)235; CHECK: br %r14236  %ptr = getelementptr i8, ptr %base, i64 524288237  %cond = icmp ult i32 %limit, 420238  %orig = load i8, ptr %ptr239  %res = select i1 %cond, i8 %orig, i8 %alt240  store i8 %res, ptr %ptr241  ret void242}243 244; Check the low end of the STCY range.245define void @f15(ptr %base, i8 %alt, i32 %limit) {246; CHECK-LABEL: f15:247; CHECK-NOT: %r2248; CHECK: blr %r14249; CHECK-NOT: %r2250; CHECK: stcy %r3, -524288(%r2)251; CHECK: br %r14252  %ptr = getelementptr i8, ptr %base, i64 -524288253  %cond = icmp ult i32 %limit, 420254  %orig = load i8, ptr %ptr255  %res = select i1 %cond, i8 %orig, i8 %alt256  store i8 %res, ptr %ptr257  ret void258}259 260; Check the next byte down, which needs separate address logic.261; Other sequences besides this one would be OK.262define void @f16(ptr %base, i8 %alt, i32 %limit) {263; CHECK-LABEL: f16:264; CHECK-NOT: %r2265; CHECK: blr %r14266; CHECK-NOT: %r2267; CHECK: agfi %r2, -524289268; CHECK: stc %r3, 0(%r2)269; CHECK: br %r14270  %ptr = getelementptr i8, ptr %base, i64 -524289271  %cond = icmp ult i32 %limit, 420272  %orig = load i8, ptr %ptr273  %res = select i1 %cond, i8 %orig, i8 %alt274  store i8 %res, ptr %ptr275  ret void276}277 278; Check that STCY allows an index.279define void @f17(i64 %base, i64 %index, i8 %alt, i32 %limit) {280; CHECK-LABEL: f17:281; CHECK-NOT: %r2282; CHECK: blr %r14283; CHECK-NOT: %r2284; CHECK: stcy %r4, 4096(%r3,%r2)285; CHECK: br %r14286  %add1 = add i64 %base, %index287  %add2 = add i64 %add1, 4096288  %ptr = inttoptr i64 %add2 to ptr289  %cond = icmp ult i32 %limit, 420290  %orig = load i8, ptr %ptr291  %res = select i1 %cond, i8 %orig, i8 %alt292  store i8 %res, ptr %ptr293  ret void294}295 296; Check that volatile loads are not matched.297define void @f18(ptr %ptr, i8 %alt, i32 %limit) {298; CHECK-LABEL: f18:299; CHECK: lb {{%r[0-5]}}, 0(%r2)300; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]301; CHECK: [[LABEL]]:302; CHECK: stc {{%r[0-5]}}, 0(%r2)303; CHECK: br %r14304  %cond = icmp ult i32 %limit, 420305  %orig = load volatile i8, ptr %ptr306  %res = select i1 %cond, i8 %orig, i8 %alt307  store i8 %res, ptr %ptr308  ret void309}310 311; ...likewise stores.  In this case we should have a conditional load into %r3.312define void @f19(ptr %ptr, i8 %alt, i32 %limit) {313; CHECK-LABEL: f19:314; CHECK: jhe [[LABEL:[^ ]*]]315; CHECK: lb %r3, 0(%r2)316; CHECK: [[LABEL]]:317; CHECK: stc %r3, 0(%r2)318; CHECK: br %r14319  %cond = icmp ult i32 %limit, 420320  %orig = load i8, ptr %ptr321  %res = select i1 %cond, i8 %orig, i8 %alt322  store volatile i8 %res, ptr %ptr323  ret void324}325 326; Check that atomic loads are not matched.  The transformation is OK for327; the "unordered" case tested here, but since we don't try to handle atomic328; operations at all in this context, it seems better to assert that than329; to restrict the test to a stronger ordering.330define void @f20(ptr %ptr, i8 %alt, i32 %limit) {331; FIXME: should use a normal load instead of CS.332; CHECK-LABEL: f20:333; CHECK: lb {{%r[0-9]+}}, 0(%r2)334; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]335; CHECK: [[LABEL]]:336; CHECK: stc {{%r[0-9]+}}, 0(%r2)337; CHECK: br %r14338  %cond = icmp ult i32 %limit, 420339  %orig = load atomic i8, ptr %ptr unordered, align 1340  %res = select i1 %cond, i8 %orig, i8 %alt341  store i8 %res, ptr %ptr342  ret void343}344 345; ...likewise stores.346define void @f21(ptr %ptr, i8 %alt, i32 %limit) {347; FIXME: should use a normal store instead of CS.348; CHECK-LABEL: f21:349; CHECK: jhe [[LABEL:[^ ]*]]350; CHECK: lb %r3, 0(%r2)351; CHECK: [[LABEL]]:352; CHECK: stc %r3, 0(%r2)353; CHECK: br %r14354  %cond = icmp ult i32 %limit, 420355  %orig = load i8, ptr %ptr356  %res = select i1 %cond, i8 %orig, i8 %alt357  store atomic i8 %res, ptr %ptr unordered, align 1358  ret void359}360 361; Try a frame index base.362define void @f22(i8 %alt, i32 %limit) {363; CHECK-LABEL: f22:364; CHECK: brasl %r14, foo@PLT365; CHECK-NOT: %r15366; CHECK: jl [[LABEL:[^ ]*]]367; CHECK-NOT: %r15368; CHECK: stc {{%r[0-9]+}}, {{[0-9]+}}(%r15)369; CHECK: [[LABEL]]:370; CHECK: brasl %r14, foo@PLT371; CHECK: br %r14372  %ptr = alloca i8373  call void @foo(ptr %ptr)374  %cond = icmp ult i32 %limit, 420375  %orig = load i8, ptr %ptr376  %res = select i1 %cond, i8 %orig, i8 %alt377  store i8 %res, ptr %ptr378  call void @foo(ptr %ptr)379  ret void380}381