mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
[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
This commit is contained in:
parent
65ddcfa8c1
commit
35c93e4e42
@ -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<LoadSDNode>(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<ConstantFPSDNode>(Op1))
|
||||
return false;
|
||||
|
||||
// Never swap comparisons with zero since there are many ways to optimize
|
||||
// those later.
|
||||
ConstantSDNode *COp1 = dyn_cast<ConstantSDNode>(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<LoadSDNode>(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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user