brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 64d0798 Raw
208 lines · plain
1; Test 64-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 with the loaded value first.8define void @f1(ptr %ptr, i64 %alt, i32 %limit) {9; CHECK-LABEL: f1:10; CHECK-NOT: %r211; CHECK: blr %r1412; CHECK-NOT: %r213; CHECK: stg %r3, 0(%r2)14; CHECK: br %r1415  %cond = icmp ult i32 %limit, 42016  %orig = load i64, ptr %ptr17  %res = select i1 %cond, i64 %orig, i64 %alt18  store i64 %res, ptr %ptr19  ret void20}21 22; ...and with the loaded value second23define void @f2(ptr %ptr, i64 %alt, i32 %limit) {24; CHECK-LABEL: f2:25; CHECK-NOT: %r226; CHECK: bher %r1427; CHECK-NOT: %r228; CHECK: stg %r3, 0(%r2)29; CHECK: br %r1430  %cond = icmp ult i32 %limit, 42031  %orig = load i64, ptr %ptr32  %res = select i1 %cond, i64 %alt, i64 %orig33  store i64 %res, ptr %ptr34  ret void35}36 37; Check the high end of the aligned STG range.38define void @f3(ptr %base, i64 %alt, i32 %limit) {39; CHECK-LABEL: f3:40; CHECK-NOT: %r241; CHECK: blr %r1442; CHECK-NOT: %r243; CHECK: stg %r3, 524280(%r2)44; CHECK: br %r1445  %ptr = getelementptr i64, ptr %base, i64 6553546  %cond = icmp ult i32 %limit, 42047  %orig = load i64, ptr %ptr48  %res = select i1 %cond, i64 %orig, i64 %alt49  store i64 %res, ptr %ptr50  ret void51}52 53; Check the next doubleword up, which needs separate address logic.54; Other sequences besides this one would be OK.55define void @f4(ptr %base, i64 %alt, i32 %limit) {56; CHECK-LABEL: f4:57; CHECK-NOT: %r258; CHECK: blr %r1459; CHECK-NOT: %r260; CHECK: agfi %r2, 52428861; CHECK: stg %r3, 0(%r2)62; CHECK: br %r1463  %ptr = getelementptr i64, ptr %base, i64 6553664  %cond = icmp ult i32 %limit, 42065  %orig = load i64, ptr %ptr66  %res = select i1 %cond, i64 %orig, i64 %alt67  store i64 %res, ptr %ptr68  ret void69}70 71; Check the low end of the STG range.72define void @f5(ptr %base, i64 %alt, i32 %limit) {73; CHECK-LABEL: f5:74; CHECK-NOT: %r275; CHECK: blr %r1476; CHECK-NOT: %r277; CHECK: stg %r3, -524288(%r2)78; CHECK: br %r1479  %ptr = getelementptr i64, ptr %base, i64 -6553680  %cond = icmp ult i32 %limit, 42081  %orig = load i64, ptr %ptr82  %res = select i1 %cond, i64 %orig, i64 %alt83  store i64 %res, ptr %ptr84  ret void85}86 87; Check the next doubleword down, which needs separate address logic.88; Other sequences besides this one would be OK.89define void @f6(ptr %base, i64 %alt, i32 %limit) {90; CHECK-LABEL: f6:91; CHECK-NOT: %r292; CHECK: blr %r1493; CHECK-NOT: %r294; CHECK: agfi %r2, -52429695; CHECK: stg %r3, 0(%r2)96; CHECK: br %r1497  %ptr = getelementptr i64, ptr %base, i64 -6553798  %cond = icmp ult i32 %limit, 42099  %orig = load i64, ptr %ptr100  %res = select i1 %cond, i64 %orig, i64 %alt101  store i64 %res, ptr %ptr102  ret void103}104 105; Check that STG allows an index.106define void @f7(i64 %base, i64 %index, i64 %alt, i32 %limit) {107; CHECK-LABEL: f7:108; CHECK-NOT: %r2109; CHECK: blr %r14110; CHECK-NOT: %r2111; CHECK: stg %r4, 524287(%r3,%r2)112; CHECK: br %r14113  %add1 = add i64 %base, %index114  %add2 = add i64 %add1, 524287115  %ptr = inttoptr i64 %add2 to ptr116  %cond = icmp ult i32 %limit, 420117  %orig = load i64, ptr %ptr118  %res = select i1 %cond, i64 %orig, i64 %alt119  store i64 %res, ptr %ptr120  ret void121}122 123; Check that volatile loads are not matched.124define void @f8(ptr %ptr, i64 %alt, i32 %limit) {125; CHECK-LABEL: f8:126; CHECK: lg {{%r[0-5]}}, 0(%r2)127; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]128; CHECK: [[LABEL]]:129; CHECK: stg {{%r[0-5]}}, 0(%r2)130; CHECK: br %r14131  %cond = icmp ult i32 %limit, 420132  %orig = load volatile i64, ptr %ptr133  %res = select i1 %cond, i64 %orig, i64 %alt134  store i64 %res, ptr %ptr135  ret void136}137 138; ...likewise stores.  In this case we should have a conditional load into %r3.139define void @f9(ptr %ptr, i64 %alt, i32 %limit) {140; CHECK-LABEL: f9:141; CHECK: jhe [[LABEL:[^ ]*]]142; CHECK: lg %r3, 0(%r2)143; CHECK: [[LABEL]]:144; CHECK: stg %r3, 0(%r2)145; CHECK: br %r14146  %cond = icmp ult i32 %limit, 420147  %orig = load i64, ptr %ptr148  %res = select i1 %cond, i64 %orig, i64 %alt149  store volatile i64 %res, ptr %ptr150  ret void151}152 153; Check that atomic loads are not matched.  The transformation is OK for154; the "unordered" case tested here, but since we don't try to handle atomic155; operations at all in this context, it seems better to assert that than156; to restrict the test to a stronger ordering.157define void @f10(ptr %ptr, i64 %alt, i32 %limit) {158; FIXME: should use a normal load instead of CSG.159; CHECK-LABEL: f10:160; CHECK: lg {{%r[0-5]}}, 0(%r2)161; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]162; CHECK: [[LABEL]]:163; CHECK: stg {{%r[0-5]}}, 0(%r2)164; CHECK: br %r14165  %cond = icmp ult i32 %limit, 420166  %orig = load atomic i64, ptr %ptr unordered, align 8167  %res = select i1 %cond, i64 %orig, i64 %alt168  store i64 %res, ptr %ptr169  ret void170}171 172; ...likewise stores.173define void @f11(ptr %ptr, i64 %alt, i32 %limit) {174; FIXME: should use a normal store instead of CSG.175; CHECK-LABEL: f11:176; CHECK: jhe [[LABEL:[^ ]*]]177; CHECK: lg %r3, 0(%r2)178; CHECK: [[LABEL]]:179; CHECK: stg %r3, 0(%r2)180; CHECK: br %r14181  %cond = icmp ult i32 %limit, 420182  %orig = load i64, ptr %ptr183  %res = select i1 %cond, i64 %orig, i64 %alt184  store atomic i64 %res, ptr %ptr unordered, align 8185  ret void186}187 188; Try a frame index base.189define void @f12(i64 %alt, i32 %limit) {190; CHECK-LABEL: f12:191; CHECK: brasl %r14, foo@PLT192; CHECK-NOT: %r15193; CHECK: jl [[LABEL:[^ ]*]]194; CHECK-NOT: %r15195; CHECK: stg {{%r[0-9]+}}, {{[0-9]+}}(%r15)196; CHECK: [[LABEL]]:197; CHECK: brasl %r14, foo@PLT198; CHECK: br %r14199  %ptr = alloca i64200  call void @foo(ptr %ptr)201  %cond = icmp ult i32 %limit, 420202  %orig = load i64, ptr %ptr203  %res = select i1 %cond, i64 %orig, i64 %alt204  store i64 %res, ptr %ptr205  call void @foo(ptr %ptr)206  ret void207}208