From 35c93e4e42d7a35a90e89211fa62f478e25ba0a4 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 23 Aug 2013 11:27:19 +0000 Subject: [PATCH] [SystemZ] Try reversing comparisons whose first operand is in memory This allows us to make more use of the many compare reg,mem instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189099 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZISelLowering.cpp | 71 ++++++++++ test/CodeGen/SystemZ/fp-cmp-01.ll | 157 +++++++++++++++++++++ test/CodeGen/SystemZ/fp-cmp-02.ll | 13 ++ test/CodeGen/SystemZ/int-cmp-01.ll | 14 ++ test/CodeGen/SystemZ/int-cmp-02.ll | 13 ++ test/CodeGen/SystemZ/int-cmp-03.ll | 13 ++ test/CodeGen/SystemZ/int-cmp-04.ll | 14 ++ test/CodeGen/SystemZ/int-cmp-05.ll | 16 ++- test/CodeGen/SystemZ/int-cmp-06.ll | 16 ++- test/CodeGen/SystemZ/int-cmp-07.ll | 13 ++ test/CodeGen/SystemZ/int-cmp-08.ll | 13 ++ test/CodeGen/SystemZ/int-cmp-36.ll | 19 +++ test/CodeGen/SystemZ/int-cmp-37.ll | 19 +++ test/CodeGen/SystemZ/int-cmp-38.ll | 18 +++ test/CodeGen/SystemZ/int-cmp-39.ll | 19 +++ test/CodeGen/SystemZ/int-cmp-40.ll | 19 +++ test/CodeGen/SystemZ/int-cmp-41.ll | 19 +++ test/CodeGen/SystemZ/int-cmp-42.ll | 19 +++ test/CodeGen/SystemZ/int-cmp-43.ll | 18 +++ 19 files changed, 501 insertions(+), 2 deletions(-) diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index a1eecd736ce..65b2ad2164f 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1110,6 +1110,69 @@ static bool preferUnsignedComparison(SelectionDAG &DAG, SDValue CmpOp0, return false; } +// Return true if Op is either an unextended load, or a load with the +// extension type given by IsUnsigned. +static bool isNaturalMemoryOperand(SDValue Op, bool IsUnsigned) { + LoadSDNode *Load = dyn_cast(Op.getNode()); + if (Load) + switch (Load->getExtensionType()) { + case ISD::NON_EXTLOAD: + case ISD::EXTLOAD: + return true; + case ISD::SEXTLOAD: + return !IsUnsigned; + case ISD::ZEXTLOAD: + return IsUnsigned; + default: + break; + } + return false; +} + +// Return true if it is better to swap comparison operands Op0 and Op1. +// IsUnsigned says whether an integer comparison is signed or unsigned. +static bool shouldSwapCmpOperands(SDValue Op0, SDValue Op1, + bool IsUnsigned) { + // Leave f128 comparisons alone, since they have no memory forms. + if (Op0.getValueType() == MVT::f128) + return false; + + // Always keep a floating-point constant second, since comparisons with + // zero can use LOAD TEST and comparisons with other constants make a + // natural memory operand. + if (isa(Op1)) + return false; + + // Never swap comparisons with zero since there are many ways to optimize + // those later. + ConstantSDNode *COp1 = dyn_cast(Op1); + if (COp1 && COp1->getZExtValue() == 0) + return false; + + // Look for cases where Cmp0 is a single-use load and Cmp1 isn't. + // In that case we generally prefer the memory to be second. + if ((isNaturalMemoryOperand(Op0, IsUnsigned) && Op0.hasOneUse()) && + !(isNaturalMemoryOperand(Op1, IsUnsigned) && Op1.hasOneUse())) { + // The only exceptions are when the second operand is a constant and + // we can use things like CHHSI. + if (!COp1) + return true; + if (IsUnsigned) { + // The memory-immediate instructions require 16-bit unsigned integers. + if (isUInt<16>(COp1->getZExtValue())) + return false; + } else { + // There are no comparisons between integers and signed memory bytes. + // The others require 16-bit signed integers. + if (cast(Op0.getNode())->getMemoryVT() == MVT::i8 || + isInt<16>(COp1->getSExtValue())) + return false; + } + return true; + } + return false; +} + // Return a target node that compares CmpOp0 with CmpOp1 and stores a // 2-bit result in CC. Set CCValid to the CCMASK_* of all possible // 2-bit results and CCMask to the subset of those results that are @@ -1131,6 +1194,14 @@ static SDValue emitCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, IsUnsigned = true; } + if (shouldSwapCmpOperands(CmpOp0, CmpOp1, IsUnsigned)) { + std::swap(CmpOp0, CmpOp1); + CCMask = ((CCMask & SystemZ::CCMASK_CMP_EQ) | + (CCMask & SystemZ::CCMASK_CMP_GT ? SystemZ::CCMASK_CMP_LT : 0) | + (CCMask & SystemZ::CCMASK_CMP_LT ? SystemZ::CCMASK_CMP_GT : 0) | + (CCMask & SystemZ::CCMASK_CMP_UO)); + } + SDLoc DL(CmpOp0); return DAG.getNode((IsUnsigned ? SystemZISD::UCMP : SystemZISD::CMP), DL, MVT::Glue, CmpOp0, CmpOp1); diff --git a/test/CodeGen/SystemZ/fp-cmp-01.ll b/test/CodeGen/SystemZ/fp-cmp-01.ll index 6a9598e30ce..7f194014f92 100644 --- a/test/CodeGen/SystemZ/fp-cmp-01.ll +++ b/test/CodeGen/SystemZ/fp-cmp-01.ll @@ -159,3 +159,160 @@ define i64 @f8(i64 %a, i64 %b, float %f) { %res = select i1 %cond, i64 %a, i64 %b ret i64 %res } + +; Check the comparison can be reversed if that allows CEB to be used, +; first with oeq. +define i64 @f9(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f9: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: je {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp oeq float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then one. +define i64 @f10(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f10: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jlh {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp one float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then olt. +define i64 @f11(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f11: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp olt float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then ole. +define i64 @f12(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f12: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jhe {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp ole float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then oge. +define i64 @f13(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f13: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jle {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp oge float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then ogt. +define i64 @f14(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f14: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jl {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp ogt float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then ueq. +define i64 @f15(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f15: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jnlh {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp ueq float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then une. +define i64 @f16(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f16: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jne {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp une float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then ult. +define i64 @f17(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f17: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jnle {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp ult float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then ule. +define i64 @f18(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f18: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jnl {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp ule float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then uge. +define i64 @f19(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f19: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jnh {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp uge float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} + +; ...then ugt. +define i64 @f20(i64 %a, i64 %b, float %f2, float *%ptr) { +; CHECK-LABEL: f20: +; CHECK: ceb %f0, 0(%r4) +; CHECK-NEXT: jnhe {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load float *%ptr + %cond = fcmp ugt float %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} diff --git a/test/CodeGen/SystemZ/fp-cmp-02.ll b/test/CodeGen/SystemZ/fp-cmp-02.ll index 309d12e824a..1cd6da8c770 100644 --- a/test/CodeGen/SystemZ/fp-cmp-02.ll +++ b/test/CodeGen/SystemZ/fp-cmp-02.ll @@ -159,3 +159,16 @@ define i64 @f8(i64 %a, i64 %b, double %f) { %res = select i1 %cond, i64 %a, i64 %b ret i64 %res } + +; Check the comparison can be reversed if that allows CDB to be used, +define i64 @f9(i64 %a, i64 %b, double %f2, double *%ptr) { +; CHECK-LABEL: f9: +; CHECK: cdb %f0, 0(%r4) +; CHECK-NEXT: jl {{\.L.*}} +; CHECK: lgr %r2, %r3 +; CHECK: br %r14 + %f1 = load double *%ptr + %cond = fcmp ogt double %f1, %f2 + %res = select i1 %cond, i64 %a, i64 %b + ret i64 %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-01.ll b/test/CodeGen/SystemZ/int-cmp-01.ll index dbfe0dfd645..6653b6f706f 100644 --- a/test/CodeGen/SystemZ/int-cmp-01.ll +++ b/test/CodeGen/SystemZ/int-cmp-01.ll @@ -149,3 +149,17 @@ define void @f10(i32 %lhs, i64 %base, i64 %index, i32 *%dst) { store i32 %res, i32 *%dst ret void } + +; Check the comparison can be reversed if that allows CH to be used. +define double @f11(double %a, double %b, i32 %rhs, i16 *%src) { +; CHECK-LABEL: f11: +; CHECK: ch %r2, 0(%r3) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: ldr %f0, %f2 +; CHECK: br %r14 + %half = load i16 *%src + %lhs = sext i16 %half to i32 + %cond = icmp slt i32 %lhs, %rhs + %res = select i1 %cond, double %a, double %b + ret double %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-02.ll b/test/CodeGen/SystemZ/int-cmp-02.ll index 26e13914349..4a8a1a9ade3 100644 --- a/test/CodeGen/SystemZ/int-cmp-02.ll +++ b/test/CodeGen/SystemZ/int-cmp-02.ll @@ -181,3 +181,16 @@ while.body: while.end: ret void } + +; Check the comparison can be reversed if that allows C to be used. +define double @f13(double %a, double %b, i32 %i2, i32 *%ptr) { +; CHECK-LABEL: f13: +; CHECK: c %r2, 0(%r3) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: ldr %f0, %f2 +; CHECK: br %r14 + %i1 = load i32 *%ptr + %cond = icmp slt i32 %i1, %i2 + %res = select i1 %cond, double %a, double %b + ret double %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-03.ll b/test/CodeGen/SystemZ/int-cmp-03.ll index 2d679cf592e..9602d54e5c7 100644 --- a/test/CodeGen/SystemZ/int-cmp-03.ll +++ b/test/CodeGen/SystemZ/int-cmp-03.ll @@ -160,3 +160,16 @@ define double @f11(double %a, double %b, i32 %i1, i64 %base, i64 %index) { %res = select i1 %cond, double %a, double %b ret double %res } + +; Check the comparison can be reversed if that allows CL to be used. +define double @f12(double %a, double %b, i32 %i2, i32 *%ptr) { +; CHECK-LABEL: f12: +; CHECK: cl %r2, 0(%r3) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: ldr %f0, %f2 +; CHECK: br %r14 + %i1 = load i32 *%ptr + %cond = icmp ult i32 %i1, %i2 + %res = select i1 %cond, double %a, double %b + ret double %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-04.ll b/test/CodeGen/SystemZ/int-cmp-04.ll index 54c4b5baad3..a6606f39292 100644 --- a/test/CodeGen/SystemZ/int-cmp-04.ll +++ b/test/CodeGen/SystemZ/int-cmp-04.ll @@ -105,3 +105,17 @@ define void @f7(i64 %lhs, i64 %base, i64 %index, i64 *%dst) { store i64 %res, i64 *%dst ret void } + +; Check the comparison can be reversed if that allows CGH to be used. +define double @f8(double %a, double %b, i64 %rhs, i16 *%src) { +; CHECK-LABEL: f8: +; CHECK: cgh %r2, 0(%r3) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: ldr %f0, %f2 +; CHECK: br %r14 + %half = load i16 *%src + %lhs = sext i16 %half to i64 + %cond = icmp slt i64 %lhs, %rhs + %res = select i1 %cond, double %a, double %b + ret double %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-05.ll b/test/CodeGen/SystemZ/int-cmp-05.ll index 36d12a5b663..f15b76bb87f 100644 --- a/test/CodeGen/SystemZ/int-cmp-05.ll +++ b/test/CodeGen/SystemZ/int-cmp-05.ll @@ -54,7 +54,7 @@ define double @f4(double %a, double %b, i64 %i1, i32 %unext) { ret double %res } -; Check signed comparisonn with memory. +; Check signed comparison with memory. define double @f5(double %a, double %b, i64 %i1, i32 *%ptr) { ; CHECK-LABEL: f5: ; CHECK: cgf %r2, 0(%r3) @@ -290,3 +290,17 @@ define i64 @f15(i32 *%ptr0) { ret i64 %sel9 } + +; Check the comparison can be reversed if that allows CGF to be used. +define double @f16(double %a, double %b, i64 %i2, i32 *%ptr) { +; CHECK-LABEL: f16: +; CHECK: cgf %r2, 0(%r3) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: ldr %f0, %f2 +; CHECK: br %r14 + %unext = load i32 *%ptr + %i1 = sext i32 %unext to i64 + %cond = icmp slt i64 %i1, %i2 + %res = select i1 %cond, double %a, double %b + ret double %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-06.ll b/test/CodeGen/SystemZ/int-cmp-06.ll index cdd61141d8d..8ab62e89ec3 100644 --- a/test/CodeGen/SystemZ/int-cmp-06.ll +++ b/test/CodeGen/SystemZ/int-cmp-06.ll @@ -104,7 +104,7 @@ define double @f8(double %a, double %b, i64 %i1, i64 %unext) { ret double %res } -; Check unsigned comparisonn with memory. +; Check unsigned comparison with memory. define double @f9(double %a, double %b, i64 %i1, i32 *%ptr) { ; CHECK-LABEL: f9: ; CHECK: clgf %r2, 0(%r3) @@ -340,3 +340,17 @@ define i64 @f19(i32 *%ptr0) { ret i64 %sel9 } + +; Check the comparison can be reversed if that allows CLGF to be used. +define double @f20(double %a, double %b, i64 %i2, i32 *%ptr) { +; CHECK-LABEL: f20: +; CHECK: clgf %r2, 0(%r3) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: ldr %f0, %f2 +; CHECK: br %r14 + %unext = load i32 *%ptr + %i1 = zext i32 %unext to i64 + %cond = icmp ult i64 %i1, %i2 + %res = select i1 %cond, double %a, double %b + ret double %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-07.ll b/test/CodeGen/SystemZ/int-cmp-07.ll index 3308cb0fb90..530d1787a77 100644 --- a/test/CodeGen/SystemZ/int-cmp-07.ll +++ b/test/CodeGen/SystemZ/int-cmp-07.ll @@ -115,3 +115,16 @@ define double @f8(double %a, double %b, i64 %i1, i64 %base, i64 %index) { %res = select i1 %cond, double %a, double %b ret double %res } + +; Check the comparison can be reversed if that allows CG to be used. +define double @f9(double %a, double %b, i64 %i2, i64 *%ptr) { +; CHECK-LABEL: f9: +; CHECK: cg %r2, 0(%r3) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: ldr %f0, %f2 +; CHECK: br %r14 + %i1 = load i64 *%ptr + %cond = icmp slt i64 %i1, %i2 + %res = select i1 %cond, double %a, double %b + ret double %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-08.ll b/test/CodeGen/SystemZ/int-cmp-08.ll index e68a0fefa04..b6f48d31815 100644 --- a/test/CodeGen/SystemZ/int-cmp-08.ll +++ b/test/CodeGen/SystemZ/int-cmp-08.ll @@ -116,3 +116,16 @@ define double @f8(double %a, double %b, i64 %i1, i64 %base, i64 %index) { %res = select i1 %cond, double %a, double %b ret double %res } + +; Check the comparison can be reversed if that allows CLG to be used. +define double @f9(double %a, double %b, i64 %i2, i64 *%ptr) { +; CHECK-LABEL: f9: +; CHECK: clg %r2, 0(%r3) +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: ldr %f0, %f2 +; CHECK: br %r14 + %i1 = load i64 *%ptr + %cond = icmp ult i64 %i1, %i2 + %res = select i1 %cond, double %a, double %b + ret double %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-36.ll b/test/CodeGen/SystemZ/int-cmp-36.ll index 831b05fdf1f..fa2d4bf6c61 100644 --- a/test/CodeGen/SystemZ/int-cmp-36.ll +++ b/test/CodeGen/SystemZ/int-cmp-36.ll @@ -100,3 +100,22 @@ exit: %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ] ret i32 %res } + +; Check the comparison can be reversed if that allows CHRL to be used. +define i32 @f6(i32 %src2) { +; CHECK-LABEL: f6: +; CHECK: chrl %r2, g +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: br %r14 +entry: + %val = load i16 *@g + %src1 = sext i16 %val to i32 + %cond = icmp slt i32 %src1, %src2 + br i1 %cond, label %exit, label %mulb +mulb: + %mul = mul i32 %src2, %src2 + br label %exit +exit: + %res = phi i32 [ %src2, %entry ], [ %mul, %mulb ] + ret i32 %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-37.ll b/test/CodeGen/SystemZ/int-cmp-37.ll index 97d210e5f56..dc11a5cba74 100644 --- a/test/CodeGen/SystemZ/int-cmp-37.ll +++ b/test/CodeGen/SystemZ/int-cmp-37.ll @@ -101,3 +101,22 @@ exit: %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ] ret i32 %res } + +; Check the comparison can be reversed if that allows CLHRL to be used. +define i32 @f6(i32 %src2) { +; CHECK-LABEL: f6: +; CHECK: clhrl %r2, g +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: br %r14 +entry: + %val = load i16 *@g + %src1 = zext i16 %val to i32 + %cond = icmp ult i32 %src1, %src2 + br i1 %cond, label %exit, label %mulb +mulb: + %mul = mul i32 %src2, %src2 + br label %exit +exit: + %res = phi i32 [ %src2, %entry ], [ %mul, %mulb ] + ret i32 %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-38.ll b/test/CodeGen/SystemZ/int-cmp-38.ll index d5a852c0c4e..90175837872 100644 --- a/test/CodeGen/SystemZ/int-cmp-38.ll +++ b/test/CodeGen/SystemZ/int-cmp-38.ll @@ -115,3 +115,21 @@ exit: %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ] ret i32 %res } + +; Check the comparison can be reversed if that allows CRL to be used. +define i32 @f7(i32 %src2) { +; CHECK-LABEL: f7: +; CHECK: crl %r2, g +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: br %r14 +entry: + %src1 = load i32 *@g + %cond = icmp slt i32 %src1, %src2 + br i1 %cond, label %exit, label %mulb +mulb: + %mul = mul i32 %src2, %src2 + br label %exit +exit: + %res = phi i32 [ %src2, %entry ], [ %mul, %mulb ] + ret i32 %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-39.ll b/test/CodeGen/SystemZ/int-cmp-39.ll index d4420583c01..fc9547d4ceb 100644 --- a/test/CodeGen/SystemZ/int-cmp-39.ll +++ b/test/CodeGen/SystemZ/int-cmp-39.ll @@ -100,3 +100,22 @@ exit: %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ] ret i64 %res } + +; Check the comparison can be reversed if that allows CGHRL to be used. +define i64 @f6(i64 %src2) { +; CHECK-LABEL: f6: +; CHECK: cghrl %r2, g +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: br %r14 +entry: + %val = load i16 *@g + %src1 = sext i16 %val to i64 + %cond = icmp slt i64 %src1, %src2 + br i1 %cond, label %exit, label %mulb +mulb: + %mul = mul i64 %src2, %src2 + br label %exit +exit: + %res = phi i64 [ %src2, %entry ], [ %mul, %mulb ] + ret i64 %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-40.ll b/test/CodeGen/SystemZ/int-cmp-40.ll index 6dab2db0d90..201d8b2fb98 100644 --- a/test/CodeGen/SystemZ/int-cmp-40.ll +++ b/test/CodeGen/SystemZ/int-cmp-40.ll @@ -101,3 +101,22 @@ exit: %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ] ret i64 %res } + +; Check the comparison can be reversed if that allows CLGHRL to be used. +define i64 @f6(i64 %src2) { +; CHECK-LABEL: f6: +; CHECK: clghrl %r2, g +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: br %r14 +entry: + %val = load i16 *@g + %src1 = zext i16 %val to i64 + %cond = icmp ult i64 %src1, %src2 + br i1 %cond, label %exit, label %mulb +mulb: + %mul = mul i64 %src2, %src2 + br label %exit +exit: + %res = phi i64 [ %src2, %entry ], [ %mul, %mulb ] + ret i64 %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-41.ll b/test/CodeGen/SystemZ/int-cmp-41.ll index 099681db42a..77f6e7d76f1 100644 --- a/test/CodeGen/SystemZ/int-cmp-41.ll +++ b/test/CodeGen/SystemZ/int-cmp-41.ll @@ -100,3 +100,22 @@ exit: %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ] ret i64 %res } + +; Check the comparison can be reversed if that allows CGFRL to be used. +define i64 @f6(i64 %src2) { +; CHECK-LABEL: f6: +; CHECK: cgfrl %r2, g +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: br %r14 +entry: + %val = load i32 *@g + %src1 = sext i32 %val to i64 + %cond = icmp slt i64 %src1, %src2 + br i1 %cond, label %exit, label %mulb +mulb: + %mul = mul i64 %src2, %src2 + br label %exit +exit: + %res = phi i64 [ %src2, %entry ], [ %mul, %mulb ] + ret i64 %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-42.ll b/test/CodeGen/SystemZ/int-cmp-42.ll index 26a268dda2b..94ef0082c44 100644 --- a/test/CodeGen/SystemZ/int-cmp-42.ll +++ b/test/CodeGen/SystemZ/int-cmp-42.ll @@ -100,3 +100,22 @@ exit: %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ] ret i64 %res } + +; Check the comparison can be reversed if that allows CLGFRL to be used. +define i64 @f6(i64 %src2) { +; CHECK-LABEL: f6: +; CHECK: clgfrl %r2, g +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: br %r14 +entry: + %val = load i32 *@g + %src1 = zext i32 %val to i64 + %cond = icmp ult i64 %src1, %src2 + br i1 %cond, label %exit, label %mulb +mulb: + %mul = mul i64 %src2, %src2 + br label %exit +exit: + %res = phi i64 [ %src2, %entry ], [ %mul, %mulb ] + ret i64 %res +} diff --git a/test/CodeGen/SystemZ/int-cmp-43.ll b/test/CodeGen/SystemZ/int-cmp-43.ll index e5e13900fd7..1a625886dec 100644 --- a/test/CodeGen/SystemZ/int-cmp-43.ll +++ b/test/CodeGen/SystemZ/int-cmp-43.ll @@ -96,3 +96,21 @@ exit: %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ] ret i64 %res } + +; Check the comparison can be reversed if that allows CGRL to be used. +define i64 @f6(i64 %src2) { +; CHECK-LABEL: f6: +; CHECK: cgrl %r2, g +; CHECK-NEXT: jh {{\.L.*}} +; CHECK: br %r14 +entry: + %src1 = load i64 *@g + %cond = icmp slt i64 %src1, %src2 + br i1 %cond, label %exit, label %mulb +mulb: + %mul = mul i64 %src2, %src2 + br label %exit +exit: + %res = phi i64 [ %src2, %entry ], [ %mul, %mulb ] + ret i64 %res +}