205 lines · plain
1; Test f32 conditional stores that are presented as selects.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5declare void @foo(ptr)6 7; Test with the loaded value first.8define void @f1(ptr %ptr, float %alt, i32 %limit) {9; CHECK-LABEL: f1:10; CHECK-NOT: %r211; CHECK: blr %r1412; CHECK-NOT: %r213; CHECK: ste %f0, 0(%r2)14; CHECK: br %r1415 %cond = icmp ult i32 %limit, 42016 %orig = load float, ptr %ptr17 %res = select i1 %cond, float %orig, float %alt18 store float %res, ptr %ptr19 ret void20}21 22; ...and with the loaded value second23define void @f2(ptr %ptr, float %alt, i32 %limit) {24; CHECK-LABEL: f2:25; CHECK-NOT: %r226; CHECK: bher %r1427; CHECK-NOT: %r228; CHECK: ste %f0, 0(%r2)29; CHECK: br %r1430 %cond = icmp ult i32 %limit, 42031 %orig = load float, ptr %ptr32 %res = select i1 %cond, float %alt, float %orig33 store float %res, ptr %ptr34 ret void35}36 37; Check the high end of the aligned STE range.38define void @f3(ptr %base, float %alt, i32 %limit) {39; CHECK-LABEL: f3:40; CHECK-NOT: %r241; CHECK: blr %r1442; CHECK-NOT: %r243; CHECK: ste %f0, 4092(%r2)44; CHECK: br %r1445 %ptr = getelementptr float, ptr %base, i64 102346 %cond = icmp ult i32 %limit, 42047 %orig = load float, ptr %ptr48 %res = select i1 %cond, float %orig, float %alt49 store float %res, ptr %ptr50 ret void51}52 53; Check the next word up, which should use STEY instead of STE.54define void @f4(ptr %base, float %alt, i32 %limit) {55; CHECK-LABEL: f4:56; CHECK-NOT: %r257; CHECK: blr %r1458; CHECK-NOT: %r259; CHECK: stey %f0, 4096(%r2)60; CHECK: br %r1461 %ptr = getelementptr float, ptr %base, i64 102462 %cond = icmp ult i32 %limit, 42063 %orig = load float, ptr %ptr64 %res = select i1 %cond, float %orig, float %alt65 store float %res, ptr %ptr66 ret void67}68 69; Check the high end of the aligned STEY range.70define void @f5(ptr %base, float %alt, i32 %limit) {71; CHECK-LABEL: f5:72; CHECK-NOT: %r273; CHECK: blr %r1474; CHECK-NOT: %r275; CHECK: stey %f0, 524284(%r2)76; CHECK: br %r1477 %ptr = getelementptr float, ptr %base, i64 13107178 %cond = icmp ult i32 %limit, 42079 %orig = load float, ptr %ptr80 %res = select i1 %cond, float %orig, float %alt81 store float %res, ptr %ptr82 ret void83}84 85; Check the next word up, which needs separate address logic.86; Other sequences besides this one would be OK.87define void @f6(ptr %base, float %alt, i32 %limit) {88; CHECK-LABEL: f6:89; CHECK-NOT: %r290; CHECK: blr %r1491; CHECK-NOT: %r292; CHECK: agfi %r2, 52428893; CHECK: ste %f0, 0(%r2)94; CHECK: br %r1495 %ptr = getelementptr float, ptr %base, i64 13107296 %cond = icmp ult i32 %limit, 42097 %orig = load float, ptr %ptr98 %res = select i1 %cond, float %orig, float %alt99 store float %res, ptr %ptr100 ret void101}102 103; Check the low end of the STEY range.104define void @f7(ptr %base, float %alt, i32 %limit) {105; CHECK-LABEL: f7:106; CHECK-NOT: %r2107; CHECK: blr %r14108; CHECK-NOT: %r2109; CHECK: stey %f0, -524288(%r2)110; CHECK: br %r14111 %ptr = getelementptr float, ptr %base, i64 -131072112 %cond = icmp ult i32 %limit, 420113 %orig = load float, ptr %ptr114 %res = select i1 %cond, float %orig, float %alt115 store float %res, ptr %ptr116 ret void117}118 119; Check the next word down, which needs separate address logic.120; Other sequences besides this one would be OK.121define void @f8(ptr %base, float %alt, i32 %limit) {122; CHECK-LABEL: f8:123; CHECK-NOT: %r2124; CHECK: blr %r14125; CHECK-NOT: %r2126; CHECK: agfi %r2, -524292127; CHECK: ste %f0, 0(%r2)128; CHECK: br %r14129 %ptr = getelementptr float, ptr %base, i64 -131073130 %cond = icmp ult i32 %limit, 420131 %orig = load float, ptr %ptr132 %res = select i1 %cond, float %orig, float %alt133 store float %res, ptr %ptr134 ret void135}136 137; Check that STEY allows an index.138define void @f9(i64 %base, i64 %index, float %alt, i32 %limit) {139; CHECK-LABEL: f9:140; CHECK-NOT: %r2141; CHECK: blr %r14142; CHECK-NOT: %r2143; CHECK: stey %f0, 4096(%r3,%r2)144; CHECK: br %r14145 %add1 = add i64 %base, %index146 %add2 = add i64 %add1, 4096147 %ptr = inttoptr i64 %add2 to ptr148 %cond = icmp ult i32 %limit, 420149 %orig = load float, ptr %ptr150 %res = select i1 %cond, float %orig, float %alt151 store float %res, ptr %ptr152 ret void153}154 155; Check that volatile loads are not matched.156define void @f10(ptr %ptr, float %alt, i32 %limit) {157; CHECK-LABEL: f10:158; CHECK: le {{%f[0-5]}}, 0(%r2)159; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]160; CHECK: [[LABEL]]:161; CHECK: ste {{%f[0-5]}}, 0(%r2)162; CHECK: br %r14163 %cond = icmp ult i32 %limit, 420164 %orig = load volatile float, ptr %ptr165 %res = select i1 %cond, float %orig, float %alt166 store float %res, ptr %ptr167 ret void168}169 170; ...likewise stores. In this case we should have a conditional load into %f0.171define void @f11(ptr %ptr, float %alt, i32 %limit) {172; CHECK-LABEL: f11:173; CHECK: jhe [[LABEL:[^ ]*]]174; CHECK: le %f0, 0(%r2)175; CHECK: [[LABEL]]:176; CHECK: ste %f0, 0(%r2)177; CHECK: br %r14178 %cond = icmp ult i32 %limit, 420179 %orig = load float, ptr %ptr180 %res = select i1 %cond, float %orig, float %alt181 store volatile float %res, ptr %ptr182 ret void183}184 185; Try a frame index base.186define void @f12(float %alt, i32 %limit) {187; CHECK-LABEL: f12:188; CHECK: brasl %r14, foo@PLT189; CHECK-NOT: %r15190; CHECK: jl [[LABEL:[^ ]*]]191; CHECK-NOT: %r15192; CHECK: ste {{%f[0-9]+}}, {{[0-9]+}}(%r15)193; CHECK: [[LABEL]]:194; CHECK: brasl %r14, foo@PLT195; CHECK: br %r14196 %ptr = alloca float197 call void @foo(ptr %ptr)198 %cond = icmp ult i32 %limit, 420199 %orig = load float, ptr %ptr200 %res = select i1 %cond, float %orig, float %alt201 store float %res, ptr %ptr202 call void @foo(ptr %ptr)203 ret void204}205