143 lines · plain
1; Test STOCFHs that are presented as selects.2; See comments in asm-18.ll about testing high-word operations.3;4; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z13 \5; RUN: -no-integrated-as | FileCheck %s6 7declare void @foo(ptr)8 9; Test the simple case, with the loaded value first.10define void @f1(ptr %ptr, i32 %limit) {11; CHECK-LABEL: f1:12; CHECK-DAG: stepa [[REG:%r[0-5]]]13; CHECK-DAG: clfi %r3, 4214; CHECK: stocfhhe [[REG]], 0(%r2)15; CHECK: br %r1416 %alt = call i32 asm "stepa $0", "=h"()17 %cond = icmp ult i32 %limit, 4218 %orig = load i32, ptr %ptr19 %res = select i1 %cond, i32 %orig, i32 %alt20 store i32 %res, ptr %ptr21 ret void22}23 24; ...and with the loaded value second25define void @f2(ptr %ptr, i32 %limit) {26; CHECK-LABEL: f2:27; CHECK-DAG: stepa [[REG:%r[0-5]]]28; CHECK-DAG: clfi %r3, 4229; CHECK: stocfhl [[REG]], 0(%r2)30; CHECK: br %r1431 %alt = call i32 asm "stepa $0", "=h"()32 %cond = icmp ult i32 %limit, 4233 %orig = load i32, ptr %ptr34 %res = select i1 %cond, i32 %alt, i32 %orig35 store i32 %res, ptr %ptr36 ret void37}38 39; Check the high end of the aligned STOC range.40define void @f3(ptr %base, i32 %limit) {41; CHECK-LABEL: f3:42; CHECK-DAG: stepa [[REG:%r[0-5]]]43; CHECK-DAG: clfi %r3, 4244; CHECK: stocfhhe [[REG]], 524284(%r2)45; CHECK: br %r1446 %alt = call i32 asm "stepa $0", "=h"()47 %ptr = getelementptr i32, ptr %base, i64 13107148 %cond = icmp ult i32 %limit, 4249 %orig = load i32, ptr %ptr50 %res = select i1 %cond, i32 %orig, i32 %alt51 store i32 %res, ptr %ptr52 ret void53}54 55; Check the next word up. Other sequences besides this one would be OK.56define void @f4(ptr %base, i32 %limit) {57; CHECK-LABEL: f4:58; CHECK-DAG: stepa [[REG:%r[0-5]]]59; CHECK-DAG: agfi %r2, 52428860; CHECK-DAG: clfi %r3, 4261; CHECK: stocfhhe [[REG]], 0(%r2)62; CHECK: br %r1463 %alt = call i32 asm "stepa $0", "=h"()64 %ptr = getelementptr i32, ptr %base, i64 13107265 %cond = icmp ult i32 %limit, 4266 %orig = load i32, ptr %ptr67 %res = select i1 %cond, i32 %orig, i32 %alt68 store i32 %res, ptr %ptr69 ret void70}71 72; Check the low end of the STOC range.73define void @f5(ptr %base, i32 %limit) {74; CHECK-LABEL: f5:75; CHECK-DAG: stepa [[REG:%r[0-5]]]76; CHECK-DAG: clfi %r3, 4277; CHECK: stocfhhe [[REG]], -524288(%r2)78; CHECK: br %r1479 %alt = call i32 asm "stepa $0", "=h"()80 %ptr = getelementptr i32, ptr %base, i64 -13107281 %cond = icmp ult i32 %limit, 4282 %orig = load i32, ptr %ptr83 %res = select i1 %cond, i32 %orig, i32 %alt84 store i32 %res, ptr %ptr85 ret void86}87 88; Check the next word down, with the same comments as f8.89define void @f6(ptr %base, i32 %limit) {90; CHECK-LABEL: f6:91; CHECK-DAG: stepa [[REG:%r[0-5]]]92; CHECK-DAG: agfi %r2, -52429293; CHECK-DAG: clfi %r3, 4294; CHECK: stocfhhe [[REG]], 0(%r2)95; CHECK: br %r1496 %alt = call i32 asm "stepa $0", "=h"()97 %ptr = getelementptr i32, ptr %base, i64 -13107398 %cond = icmp ult i32 %limit, 4299 %orig = load i32, ptr %ptr100 %res = select i1 %cond, i32 %orig, i32 %alt101 store i32 %res, ptr %ptr102 ret void103}104 105; Try a frame index base.106define void @f7(i32 %limit) {107; CHECK-LABEL: f7:108; CHECK: brasl %r14, foo@PLT109; CHECK: stepa [[REG:%r[0-5]]]110; CHECK: stocfhhe [[REG]], {{[0-9]+}}(%r15)111; CHECK: brasl %r14, foo@PLT112; CHECK: br %r14113 %ptr = alloca i32114 call void @foo(ptr %ptr)115 %alt = call i32 asm "stepa $0", "=h"()116 %cond = icmp ult i32 %limit, 42117 %orig = load i32, ptr %ptr118 %res = select i1 %cond, i32 %orig, i32 %alt119 store i32 %res, ptr %ptr120 call void @foo(ptr %ptr)121 ret void122}123 124; Test that conditionally-executed stores do not use STOC, since STOC125; is allowed to trap even when the condition is false.126define void @f8(i32 %a, i32 %b, ptr %dest) {127; CHECK-LABEL: f8:128; CHECK-NOT: stoc129; CHECK: stfh130; CHECK: br %r14131entry:132 %val = call i32 asm "stepa $0", "=h"()133 %cmp = icmp ule i32 %a, %b134 br i1 %cmp, label %store, label %exit135 136store:137 store i32 %val, ptr %dest138 br label %exit139 140exit:141 ret void142}143