145 lines · plain
1; Test LOCG.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s4 5declare i64 @foo(ptr)6 7; Test the simple case.8define i64 @f1(i64 %easy, ptr %ptr, i64 %limit) {9; CHECK-LABEL: f1:10; CHECK: clgfi %r4, 4211; CHECK: locghe %r2, 0(%r3)12; CHECK: br %r1413 %cond = icmp ult i64 %limit, 4214 %other = load i64, ptr %ptr15 %res = select i1 %cond, i64 %easy, i64 %other16 ret i64 %res17}18 19; ...and again with the operands swapped.20define i64 @f2(i64 %easy, ptr %ptr, i64 %limit) {21; CHECK-LABEL: f2:22; CHECK: clgfi %r4, 4223; CHECK: locgl %r2, 0(%r3)24; CHECK: br %r1425 %cond = icmp ult i64 %limit, 4226 %other = load i64, ptr %ptr27 %res = select i1 %cond, i64 %other, i64 %easy28 ret i64 %res29}30 31; Check the high end of the aligned LOCG range.32define i64 @f3(i64 %easy, ptr %base, i64 %limit) {33; CHECK-LABEL: f3:34; CHECK: clgfi %r4, 4235; CHECK: locghe %r2, 524280(%r3)36; CHECK: br %r1437 %ptr = getelementptr i64, ptr %base, i64 6553538 %cond = icmp ult i64 %limit, 4239 %other = load i64, ptr %ptr40 %res = select i1 %cond, i64 %easy, i64 %other41 ret i64 %res42}43 44; Check the next doubleword up. Other sequences besides this one would be OK.45define i64 @f4(i64 %easy, ptr %base, i64 %limit) {46; CHECK-LABEL: f4:47; CHECK: agfi %r3, 52428848; CHECK: clgfi %r4, 4249; CHECK: locghe %r2, 0(%r3)50; CHECK: br %r1451 %ptr = getelementptr i64, ptr %base, i64 6553652 %cond = icmp ult i64 %limit, 4253 %other = load i64, ptr %ptr54 %res = select i1 %cond, i64 %easy, i64 %other55 ret i64 %res56}57 58; Check the low end of the LOCG range.59define i64 @f5(i64 %easy, ptr %base, i64 %limit) {60; CHECK-LABEL: f5:61; CHECK: clgfi %r4, 4262; CHECK: locghe %r2, -524288(%r3)63; CHECK: br %r1464 %ptr = getelementptr i64, ptr %base, i64 -6553665 %cond = icmp ult i64 %limit, 4266 %other = load i64, ptr %ptr67 %res = select i1 %cond, i64 %easy, i64 %other68 ret i64 %res69}70 71; Check the next doubleword down, with the same comments as f4.72define i64 @f6(i64 %easy, ptr %base, i64 %limit) {73; CHECK-LABEL: f6:74; CHECK: agfi %r3, -52429675; CHECK: clgfi %r4, 4276; CHECK: locghe %r2, 0(%r3)77; CHECK: br %r1478 %ptr = getelementptr i64, ptr %base, i64 -6553779 %cond = icmp ult i64 %limit, 4280 %other = load i64, ptr %ptr81 %res = select i1 %cond, i64 %easy, i64 %other82 ret i64 %res83}84 85; Try a frame index base.86define i64 @f7(i64 %alt, i64 %limit) {87; CHECK-LABEL: f7:88; CHECK: brasl %r14, foo@PLT89; CHECK: locghe %r2, {{[0-9]+}}(%r15)90; CHECK: br %r1491 %ptr = alloca i6492 %easy = call i64 @foo(ptr %ptr)93 %cond = icmp ult i64 %limit, 4294 %other = load i64, ptr %ptr95 %res = select i1 %cond, i64 %easy, i64 %other96 ret i64 %res97}98 99; Try a case when an index is involved.100define i64 @f8(i64 %easy, i64 %limit, i64 %base, i64 %index) {101; CHECK-LABEL: f8:102; CHECK: clgfi %r3, 42103; CHECK: locghe %r2, 0({{%r[1-5]}})104; CHECK: br %r14105 %add = add i64 %base, %index106 %ptr = inttoptr i64 %add to ptr107 %cond = icmp ult i64 %limit, 42108 %other = load i64, ptr %ptr109 %res = select i1 %cond, i64 %easy, i64 %other110 ret i64 %res111}112 113; Test that conditionally-executed loads do not use LOCG, since it is allowed114; to trap even when the condition is false.115define i64 @f9(i64 %easy, i64 %limit, ptr %ptr) {116; CHECK-LABEL: f9:117; CHECK-NOT: locg118; CHECK: br %r14119entry:120 %cmp = icmp ule i64 %easy, %limit121 br i1 %cmp, label %load, label %exit122 123load:124 %other = load i64, ptr %ptr125 br label %exit126 127exit:128 %res = phi i64 [ %easy, %entry ], [ %other, %load ]129 ret i64 %res130}131 132; Test that volatile loads do not use LOCG, since if the condition is false,133; it is unspecified whether or not the load happens. LOCGR is fine though.134define i64 @f10(i64 %easy, ptr %ptr, i64 %limit) {135; CHECK-LABEL: f10:136; CHECK: lg {{%r[0-9]*}}, 0(%r3)137; CHECK: locgr138; CHECK: br %r14139 %cond = icmp ult i64 %limit, 42140 %other = load volatile i64, ptr %ptr141 %res = select i1 %cond, i64 %easy, i64 %other142 ret i64 %res143}144 145