1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[CGP] Make ICMP_EQ use CR result of ICMP_S(L|G)T dominators

For example:

long long test(long long a, long long b) {
  if (a << b > 0)
    return b;
  if (a << b < 0)
    return a;
  return a*b;
}

Produces:

        sld. 5, 3, 4
        ble 0, .LBB0_2
        mr 3, 4
        blr
.LBB0_2:                                # %if.end
        cmpldi  5, 0
        li 5, 1
        isel 4, 4, 5, 2
        mulld 3, 4, 3
        blr

But the compare (cmpldi 5, 0) is redundant and can be removed (CR0 already
contains the result of that comparison).

The root cause of this is that LLVM converts signed comparisons into equality
comparison based on dominance. Equality comparisons are unsigned by default, so
we get either a record-form or cmp (without the l for logical) feeding a cmpl.
That is the situation we want to avoid here.

Differential Revision: https://reviews.llvm.org/D60506
This commit is contained in:
Yi-Hong Lyu 2019-11-11 16:15:52 +00:00
parent 63b6fc635a
commit 886fba1618
6 changed files with 227 additions and 149 deletions

View File

@ -472,6 +472,10 @@ public:
return false; return false;
} }
/// Return true if instruction generated for equality comparison is folded
/// with instruction generated for signed comparison.
virtual bool isEqualityCmpFoldedWithSignedCmp() const { return true; }
/// Return true if it is safe to transform an integer-domain bitwise operation /// Return true if it is safe to transform an integer-domain bitwise operation
/// into the equivalent floating-point operation. This should be set to true /// into the equivalent floating-point operation. This should be set to true
/// if the target has IEEE-754-compliant fabs/fneg operations for the input /// if the target has IEEE-754-compliant fabs/fneg operations for the input

View File

@ -222,6 +222,10 @@ static cl::opt<bool>
cl::init(true), cl::init(true),
cl::desc("Enable splitting large offset of GEP.")); cl::desc("Enable splitting large offset of GEP."));
static cl::opt<bool> EnableICMP_EQToICMP_ST(
"cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false),
cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
namespace { namespace {
enum ExtType { enum ExtType {
@ -1408,6 +1412,93 @@ static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI) {
return MadeChange; return MadeChange;
} }
/// For pattern like:
///
/// DomCond = icmp sgt/slt CmpOp0, CmpOp1 (might not be in DomBB)
/// ...
/// DomBB:
/// ...
/// br DomCond, TrueBB, CmpBB
/// CmpBB: (with DomBB being the single predecessor)
/// ...
/// Cmp = icmp eq CmpOp0, CmpOp1
/// ...
///
/// It would use two comparison on targets that lowering of icmp sgt/slt is
/// different from lowering of icmp eq (PowerPC). This function try to convert
/// 'Cmp = icmp eq CmpOp0, CmpOp1' to ' Cmp = icmp slt/sgt CmpOp0, CmpOp1'.
/// After that, DomCond and Cmp can use the same comparison so reduce one
/// comparison.
///
/// Return true if any changes are made.
static bool foldICmpWithDominatingICmp(CmpInst *Cmp,
const TargetLowering &TLI) {
if (!EnableICMP_EQToICMP_ST && TLI.isEqualityCmpFoldedWithSignedCmp())
return false;
ICmpInst::Predicate Pred = Cmp->getPredicate();
if (Pred != ICmpInst::ICMP_EQ)
return false;
// If icmp eq has users other than BranchInst and SelectInst, converting it to
// icmp slt/sgt would introduce more redundant LLVM IR.
for (User *U : Cmp->users()) {
if (isa<BranchInst>(U))
continue;
if (isa<SelectInst>(U) && cast<SelectInst>(U)->getCondition() == Cmp)
continue;
return false;
}
// This is a cheap/incomplete check for dominance - just match a single
// predecessor with a conditional branch.
BasicBlock *CmpBB = Cmp->getParent();
BasicBlock *DomBB = CmpBB->getSinglePredecessor();
if (!DomBB)
return false;
// We want to ensure that the only way control gets to the comparison of
// interest is that a less/greater than comparison on the same operands is
// false.
Value *DomCond;
BasicBlock *TrueBB, *FalseBB;
if (!match(DomBB->getTerminator(), m_Br(m_Value(DomCond), TrueBB, FalseBB)))
return false;
if (CmpBB != FalseBB)
return false;
Value *CmpOp0 = Cmp->getOperand(0), *CmpOp1 = Cmp->getOperand(1);
ICmpInst::Predicate DomPred;
if (!match(DomCond, m_ICmp(DomPred, m_Specific(CmpOp0), m_Specific(CmpOp1))))
return false;
if (DomPred != ICmpInst::ICMP_SGT && DomPred != ICmpInst::ICMP_SLT)
return false;
// Convert the equality comparison to the opposite of the dominating
// comparison and swap the direction for all branch/select users.
// We have conceptually converted:
// Res = (a < b) ? <LT_RES> : (a == b) ? <EQ_RES> : <GT_RES>;
// to
// Res = (a < b) ? <LT_RES> : (a > b) ? <GT_RES> : <EQ_RES>;
// And similarly for branches.
for (User *U : Cmp->users()) {
if (auto *BI = dyn_cast<BranchInst>(U)) {
assert(BI->isConditional() && "Must be conditional");
BI->swapSuccessors();
continue;
}
if (auto *SI = dyn_cast<SelectInst>(U)) {
// Swap operands
SI->swapValues();
SI->swapProfMetadata();
continue;
}
llvm_unreachable("Must be a branch or a select");
}
Cmp->setPredicate(CmpInst::getSwappedPredicate(DomPred));
return true;
}
bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, bool &ModifiedDT) { bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, bool &ModifiedDT) {
if (sinkCmpExpression(Cmp, *TLI)) if (sinkCmpExpression(Cmp, *TLI))
return true; return true;
@ -1418,6 +1509,9 @@ bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, bool &ModifiedDT) {
if (combineToUSubWithOverflow(Cmp, ModifiedDT)) if (combineToUSubWithOverflow(Cmp, ModifiedDT))
return true; return true;
if (foldICmpWithDominatingICmp(Cmp, *TLI))
return true;
return false; return false;
} }

View File

@ -650,6 +650,10 @@ namespace llvm {
return true; return true;
} }
bool isEqualityCmpFoldedWithSignedCmp() const override {
return false;
}
bool hasAndNotCompare(SDValue) const override { bool hasAndNotCompare(SDValue) const override {
return true; return true;
} }

View File

@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=aarch64-unknown-unknown -O3 -verify-machineinstrs < %s | FileCheck %s ; RUN: llc -mtriple=aarch64-unknown-unknown -O3 -cgp-icmp-eq2icmp-st -verify-machineinstrs < %s | FileCheck %s
; Test cases are generated from: ; Test cases are generated from:
; long long NAME(PARAM a, PARAM b) { ; long long NAME(PARAM a, PARAM b) {
@ -24,7 +24,7 @@ define i64 @ll_a_op_b__2(i64 %a, i64 %b) {
; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB0_2: // %if.end ; CHECK-NEXT: .LBB0_2: // %if.end
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -52,7 +52,7 @@ define i64 @ll_a_op_b__1(i64 %a, i64 %b) {
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB1_2: // %if.end ; CHECK-NEXT: .LBB1_2: // %if.end
; CHECK-NEXT: cmn x8, #1 // =1 ; CHECK-NEXT: cmn x8, #1 // =1
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -80,7 +80,7 @@ define i64 @ll_a_op_b_0(i64 %a, i64 %b) {
; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB2_2: // %if.end ; CHECK-NEXT: .LBB2_2: // %if.end
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -108,7 +108,7 @@ define i64 @ll_a_op_b_1(i64 %a, i64 %b) {
; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB3_2: // %if.end ; CHECK-NEXT: .LBB3_2: // %if.end
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -136,7 +136,7 @@ define i64 @ll_a_op_b_2(i64 %a, i64 %b) {
; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB4_2: // %if.end ; CHECK-NEXT: .LBB4_2: // %if.end
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -163,7 +163,7 @@ define i64 @ll_a__2(i64 %a, i64 %b) {
; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB5_2: // %if.end ; CHECK-NEXT: .LBB5_2: // %if.end
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -189,7 +189,7 @@ define i64 @ll_a__1(i64 %a, i64 %b) {
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB6_2: // %if.end ; CHECK-NEXT: .LBB6_2: // %if.end
; CHECK-NEXT: cmn x0, #1 // =1 ; CHECK-NEXT: cmn x0, #1 // =1
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -215,7 +215,7 @@ define i64 @ll_a_0(i64 %a, i64 %b) {
; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB7_2: // %if.end ; CHECK-NEXT: .LBB7_2: // %if.end
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -241,7 +241,7 @@ define i64 @ll_a_1(i64 %a, i64 %b) {
; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB8_2: // %if.end ; CHECK-NEXT: .LBB8_2: // %if.end
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
@ -267,7 +267,7 @@ define i64 @ll_a_2(i64 %a, i64 %b) {
; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret ; CHECK-NEXT: ret
; CHECK-NEXT: .LBB9_2: // %if.end ; CHECK-NEXT: .LBB9_2: // %if.end
; CHECK-NEXT: csinc x8, x1, xzr, eq ; CHECK-NEXT: csinc x8, x1, xzr, ge
; CHECK-NEXT: mul x0, x8, x0 ; CHECK-NEXT: mul x0, x8, x0
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:

View File

@ -25,7 +25,7 @@ define i64 @ll_a_op_b__2(i64 %a, i64 %b) {
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB0_2: # %if.end ; CHECK-NEXT: .LBB0_2: # %if.end
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -54,7 +54,7 @@ define i64 @ll_a_op_b__1(i64 %a, i64 %b) {
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB1_2: # %if.end ; CHECK-NEXT: .LBB1_2: # %if.end
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -81,9 +81,8 @@ define i64 @ll_a_op_b_0(i64 %a, i64 %b) {
; CHECK-NEXT: mr r3, r4 ; CHECK-NEXT: mr r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB2_2: # %if.end ; CHECK-NEXT: .LBB2_2: # %if.end
; CHECK-NEXT: cmpldi r5, 0
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -111,9 +110,8 @@ define i64 @ll_a_op_b_1(i64 %a, i64 %b) {
; CHECK-NEXT: mr r3, r4 ; CHECK-NEXT: mr r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB3_2: # %if.end ; CHECK-NEXT: .LBB3_2: # %if.end
; CHECK-NEXT: cmpldi r5, 1
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -141,9 +139,8 @@ define i64 @ll_a_op_b_2(i64 %a, i64 %b) {
; CHECK-NEXT: mr r3, r4 ; CHECK-NEXT: mr r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB4_2: # %if.end ; CHECK-NEXT: .LBB4_2: # %if.end
; CHECK-NEXT: cmpldi r5, 2
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -171,7 +168,7 @@ define i64 @ll_a__2(i64 %a, i64 %b) {
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB5_2: # %if.end ; CHECK-NEXT: .LBB5_2: # %if.end
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -198,7 +195,7 @@ define i64 @ll_a__1(i64 %a, i64 %b) {
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB6_2: # %if.end ; CHECK-NEXT: .LBB6_2: # %if.end
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -224,9 +221,8 @@ define i64 @ll_a_0(i64 %a, i64 %b) {
; CHECK-NEXT: mr r3, r4 ; CHECK-NEXT: mr r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB7_2: # %if.end ; CHECK-NEXT: .LBB7_2: # %if.end
; CHECK-NEXT: cmpldi r3, 0
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -252,9 +248,8 @@ define i64 @ll_a_1(i64 %a, i64 %b) {
; CHECK-NEXT: mr r3, r4 ; CHECK-NEXT: mr r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB8_2: # %if.end ; CHECK-NEXT: .LBB8_2: # %if.end
; CHECK-NEXT: cmpldi r3, 1
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -280,9 +275,8 @@ define i64 @ll_a_2(i64 %a, i64 %b) {
; CHECK-NEXT: mr r3, r4 ; CHECK-NEXT: mr r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB9_2: # %if.end ; CHECK-NEXT: .LBB9_2: # %if.end
; CHECK-NEXT: cmpldi r3, 2
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mulld r3, r4, r3 ; CHECK-NEXT: mulld r3, r4, r3
; CHECK-NEXT: blr ; CHECK-NEXT: blr
entry: entry:
@ -307,7 +301,7 @@ define i64 @i_a_op_b__2(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: bgt cr0, .LBB10_2 ; CHECK-NEXT: bgt cr0, .LBB10_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: .LBB10_2: # %return ; CHECK-NEXT: .LBB10_2: # %return
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
@ -340,7 +334,7 @@ define i64 @i_a_op_b__1(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB11_2: # %if.end ; CHECK-NEXT: .LBB11_2: # %if.end
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
@ -371,9 +365,8 @@ define i64 @i_a_op_b_0(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB12_2: # %if.end ; CHECK-NEXT: .LBB12_2: # %if.end
; CHECK-NEXT: cmplwi r5, 0
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
@ -401,9 +394,8 @@ define i64 @i_a_op_b_1(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: cmpwi r5, 1 ; CHECK-NEXT: cmpwi r5, 1
; CHECK-NEXT: bgt cr0, .LBB13_2 ; CHECK-NEXT: bgt cr0, .LBB13_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: cmplwi r5, 1
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: .LBB13_2: # %return ; CHECK-NEXT: .LBB13_2: # %return
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
@ -432,9 +424,8 @@ define i64 @i_a_op_b_2(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: cmpwi r5, 2 ; CHECK-NEXT: cmpwi r5, 2
; CHECK-NEXT: bgt cr0, .LBB14_2 ; CHECK-NEXT: bgt cr0, .LBB14_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: cmplwi r5, 2
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: .LBB14_2: # %return ; CHECK-NEXT: .LBB14_2: # %return
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
@ -463,7 +454,7 @@ define i64 @i_a__2(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: bgt cr0, .LBB15_2 ; CHECK-NEXT: bgt cr0, .LBB15_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: .LBB15_2: # %return ; CHECK-NEXT: .LBB15_2: # %return
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
@ -494,7 +485,7 @@ define i64 @i_a__1(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB16_2: # %if.end ; CHECK-NEXT: .LBB16_2: # %if.end
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
@ -523,9 +514,8 @@ define i64 @i_a_0(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
; CHECK-NEXT: .LBB17_2: # %if.end ; CHECK-NEXT: .LBB17_2: # %if.end
; CHECK-NEXT: cmplwi r3, 0
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
; CHECK-NEXT: blr ; CHECK-NEXT: blr
@ -551,9 +541,8 @@ define i64 @i_a_1(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: cmpwi r3, 1 ; CHECK-NEXT: cmpwi r3, 1
; CHECK-NEXT: bgt cr0, .LBB18_2 ; CHECK-NEXT: bgt cr0, .LBB18_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: cmplwi r3, 1
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: .LBB18_2: # %return ; CHECK-NEXT: .LBB18_2: # %return
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4
@ -580,9 +569,8 @@ define i64 @i_a_2(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: cmpwi r3, 2 ; CHECK-NEXT: cmpwi r3, 2
; CHECK-NEXT: bgt cr0, .LBB19_2 ; CHECK-NEXT: bgt cr0, .LBB19_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: cmplwi r3, 2
; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: li r5, 1
; CHECK-NEXT: isel r4, r4, r5, eq ; CHECK-NEXT: isel r4, r5, r4, lt
; CHECK-NEXT: mullw r4, r4, r3 ; CHECK-NEXT: mullw r4, r4, r3
; CHECK-NEXT: .LBB19_2: # %return ; CHECK-NEXT: .LBB19_2: # %return
; CHECK-NEXT: extsw r3, r4 ; CHECK-NEXT: extsw r3, r4

View File

@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=x86_64-unknown-unknown -O3 -verify-machineinstrs < %s | FileCheck %s ; RUN: llc -mtriple=x86_64-unknown-unknown -O3 -cgp-icmp-eq2icmp-st -verify-machineinstrs < %s | FileCheck %s
; Test cases are generated from: ; Test cases are generated from:
; long long NAME(PARAM a, PARAM b) { ; long long NAME(PARAM a, PARAM b) {
@ -17,18 +17,17 @@ target datalayout = "e-m:e-i64:64-n32:64"
define i64 @ll_a_op_b__2(i64 %a, i64 %b) { define i64 @ll_a_op_b__2(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a_op_b__2: ; CHECK-LABEL: ll_a_op_b__2:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx ; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: movq %rdi, %rdx
; CHECK-NEXT: shlq %cl, %rax ; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: cmpq $-2, %rax ; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: jle .LBB0_1 ; CHECK-NEXT: cmpq $-2, %rdx
; CHECK-NEXT: # %bb.2: # %return ; CHECK-NEXT: jg .LBB0_2
; CHECK-NEXT: movq %rcx, %rax ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: retq ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: .LBB0_1: # %if.end ; CHECK-NEXT: cmovlq %rcx, %rax
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmoveq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: .LBB0_2: # %return
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
%shl = shl i64 %a, %b %shl = shl i64 %a, %b
@ -48,18 +47,18 @@ return: ; preds = %entry
define i64 @ll_a_op_b__1(i64 %a, i64 %b) { define i64 @ll_a_op_b__1(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a_op_b__1: ; CHECK-LABEL: ll_a_op_b__1:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx ; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: movq %rdi, %rdx
; CHECK-NEXT: shlq %cl, %rax ; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: testq %rax, %rax ; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: testq %rdx, %rdx
; CHECK-NEXT: js .LBB1_1 ; CHECK-NEXT: js .LBB1_1
; CHECK-NEXT: # %bb.2: # %return ; CHECK-NEXT: # %bb.2: # %return
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
; CHECK-NEXT: .LBB1_1: # %if.end ; CHECK-NEXT: .LBB1_1: # %if.end
; CHECK-NEXT: cmpq $-1, %rax ; CHECK-NEXT: cmpq $-1, %rdx
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: cmovlq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
@ -80,17 +79,17 @@ return: ; preds = %entry
define i64 @ll_a_op_b_0(i64 %a, i64 %b) { define i64 @ll_a_op_b_0(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a_op_b_0: ; CHECK-LABEL: ll_a_op_b_0:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx ; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: movq %rdi, %rdx
; CHECK-NEXT: shlq %cl, %rax ; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: testq %rax, %rax ; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: testq %rdx, %rdx
; CHECK-NEXT: jle .LBB2_1 ; CHECK-NEXT: jle .LBB2_1
; CHECK-NEXT: # %bb.2: # %return ; CHECK-NEXT: # %bb.2: # %return
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
; CHECK-NEXT: .LBB2_1: # %if.end ; CHECK-NEXT: .LBB2_1: # %if.end
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: cmovsq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
@ -111,18 +110,18 @@ return: ; preds = %entry
define i64 @ll_a_op_b_1(i64 %a, i64 %b) { define i64 @ll_a_op_b_1(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a_op_b_1: ; CHECK-LABEL: ll_a_op_b_1:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx ; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: movq %rdi, %rdx
; CHECK-NEXT: shlq %cl, %rax ; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: cmpq $1, %rax ; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: jle .LBB3_1 ; CHECK-NEXT: cmpq $1, %rdx
; CHECK-NEXT: # %bb.2: # %return ; CHECK-NEXT: jg .LBB3_2
; CHECK-NEXT: movq %rcx, %rax ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: retq ; CHECK-NEXT: testq %rdx, %rdx
; CHECK-NEXT: .LBB3_1: # %if.end ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: cmovleq %rcx, %rax
; CHECK-NEXT: cmoveq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: .LBB3_2: # %return
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
%shl = shl i64 %a, %b %shl = shl i64 %a, %b
@ -142,18 +141,17 @@ return: ; preds = %entry
define i64 @ll_a_op_b_2(i64 %a, i64 %b) { define i64 @ll_a_op_b_2(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a_op_b_2: ; CHECK-LABEL: ll_a_op_b_2:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx ; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: movq %rdi, %rdx
; CHECK-NEXT: shlq %cl, %rax ; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: cmpq $2, %rax ; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: jle .LBB4_1 ; CHECK-NEXT: cmpq $2, %rdx
; CHECK-NEXT: # %bb.2: # %return ; CHECK-NEXT: jg .LBB4_2
; CHECK-NEXT: movq %rcx, %rax ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: retq ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: .LBB4_1: # %if.end ; CHECK-NEXT: cmovlq %rcx, %rax
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmoveq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: .LBB4_2: # %return
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
%shl = shl i64 %a, %b %shl = shl i64 %a, %b
@ -173,15 +171,14 @@ return: ; preds = %entry
define i64 @ll_a__2(i64 %a, i64 %b) { define i64 @ll_a__2(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a__2: ; CHECK-LABEL: ll_a__2:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cmpq $-2, %rdi
; CHECK-NEXT: jle .LBB5_1
; CHECK-NEXT: # %bb.2: # %return
; CHECK-NEXT: movq %rsi, %rax ; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: cmpq $-2, %rdi
; CHECK-NEXT: .LBB5_1: # %if.end ; CHECK-NEXT: jg .LBB5_2
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: cmoveq %rsi, %rax ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: cmovlq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: .LBB5_2: # %return
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
%cmp = icmp sgt i64 %a, -2 %cmp = icmp sgt i64 %a, -2
@ -200,15 +197,15 @@ return: ; preds = %entry
define i64 @ll_a__1(i64 %a, i64 %b) { define i64 @ll_a__1(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a__1: ; CHECK-LABEL: ll_a__1:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: testq %rdi, %rdi ; CHECK-NEXT: testq %rdi, %rdi
; CHECK-NEXT: js .LBB6_1 ; CHECK-NEXT: js .LBB6_1
; CHECK-NEXT: # %bb.2: # %return ; CHECK-NEXT: # %bb.2: # %return
; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
; CHECK-NEXT: .LBB6_1: # %if.end ; CHECK-NEXT: .LBB6_1: # %if.end
; CHECK-NEXT: cmpq $-1, %rdi ; CHECK-NEXT: cmpq $-1, %rdi
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: cmoveq %rsi, %rax ; CHECK-NEXT: cmovlq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
@ -228,14 +225,14 @@ return: ; preds = %entry
define i64 @ll_a_0(i64 %a, i64 %b) { define i64 @ll_a_0(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a_0: ; CHECK-LABEL: ll_a_0:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: testq %rdi, %rdi ; CHECK-NEXT: testq %rdi, %rdi
; CHECK-NEXT: jle .LBB7_1 ; CHECK-NEXT: jle .LBB7_1
; CHECK-NEXT: # %bb.2: # %return ; CHECK-NEXT: # %bb.2: # %return
; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
; CHECK-NEXT: .LBB7_1: # %if.end ; CHECK-NEXT: .LBB7_1: # %if.end
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: cmoveq %rsi, %rax ; CHECK-NEXT: cmovsq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
@ -255,15 +252,15 @@ return: ; preds = %entry
define i64 @ll_a_1(i64 %a, i64 %b) { define i64 @ll_a_1(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a_1: ; CHECK-LABEL: ll_a_1:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cmpq $1, %rdi
; CHECK-NEXT: jle .LBB8_1
; CHECK-NEXT: # %bb.2: # %return
; CHECK-NEXT: movq %rsi, %rax ; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: cmpq $1, %rdi
; CHECK-NEXT: .LBB8_1: # %if.end ; CHECK-NEXT: jg .LBB8_2
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: cmoveq %rsi, %rax ; CHECK-NEXT: testq %rdi, %rdi
; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: cmovleq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: .LBB8_2: # %return
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
%cmp = icmp sgt i64 %a, 1 %cmp = icmp sgt i64 %a, 1
@ -282,15 +279,14 @@ return: ; preds = %entry
define i64 @ll_a_2(i64 %a, i64 %b) { define i64 @ll_a_2(i64 %a, i64 %b) {
; CHECK-LABEL: ll_a_2: ; CHECK-LABEL: ll_a_2:
; CHECK: # %bb.0: # %entry ; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cmpq $2, %rdi
; CHECK-NEXT: jle .LBB9_1
; CHECK-NEXT: # %bb.2: # %return
; CHECK-NEXT: movq %rsi, %rax ; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: cmpq $2, %rdi
; CHECK-NEXT: .LBB9_1: # %if.end ; CHECK-NEXT: jg .LBB9_2
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: cmoveq %rsi, %rax ; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: cmovlq %rcx, %rax
; CHECK-NEXT: imulq %rdi, %rax ; CHECK-NEXT: imulq %rdi, %rax
; CHECK-NEXT: .LBB9_2: # %return
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
%cmp = icmp sgt i64 %a, 2 %cmp = icmp sgt i64 %a, 2
@ -316,9 +312,8 @@ define i64 @i_a_op_b__2(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: jg .LBB10_2 ; CHECK-NEXT: jg .LBB10_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %ecx, %eax ; CHECK-NEXT: cmovll %eax, %ecx
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %ecx
; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: .LBB10_2: # %return ; CHECK-NEXT: .LBB10_2: # %return
; CHECK-NEXT: movslq %ecx, %rax ; CHECK-NEXT: movslq %ecx, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
@ -353,9 +348,8 @@ define i64 @i_a_op_b__1(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: .LBB11_1: # %if.end ; CHECK-NEXT: .LBB11_1: # %if.end
; CHECK-NEXT: cmpl $-1, %eax ; CHECK-NEXT: cmpl $-1, %eax
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %ecx, %eax ; CHECK-NEXT: cmovll %eax, %ecx
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %ecx
; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: movslq %ecx, %rax ; CHECK-NEXT: movslq %ecx, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
@ -388,9 +382,8 @@ define i64 @i_a_op_b_0(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: retq ; CHECK-NEXT: retq
; CHECK-NEXT: .LBB12_1: # %if.end ; CHECK-NEXT: .LBB12_1: # %if.end
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %ecx, %eax ; CHECK-NEXT: cmovsl %eax, %ecx
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %ecx
; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: movslq %ecx, %rax ; CHECK-NEXT: movslq %ecx, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
@ -419,10 +412,10 @@ define i64 @i_a_op_b_1(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: cmpl $1, %eax ; CHECK-NEXT: cmpl $1, %eax
; CHECK-NEXT: jg .LBB13_2 ; CHECK-NEXT: jg .LBB13_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: testl %eax, %eax
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %ecx, %eax ; CHECK-NEXT: cmovlel %eax, %ecx
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %ecx
; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: .LBB13_2: # %return ; CHECK-NEXT: .LBB13_2: # %return
; CHECK-NEXT: movslq %ecx, %rax ; CHECK-NEXT: movslq %ecx, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
@ -453,9 +446,8 @@ define i64 @i_a_op_b_2(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: jg .LBB14_2 ; CHECK-NEXT: jg .LBB14_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %ecx, %eax ; CHECK-NEXT: cmovll %eax, %ecx
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %ecx
; CHECK-NEXT: movl %eax, %ecx
; CHECK-NEXT: .LBB14_2: # %return ; CHECK-NEXT: .LBB14_2: # %return
; CHECK-NEXT: movslq %ecx, %rax ; CHECK-NEXT: movslq %ecx, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
@ -483,9 +475,8 @@ define i64 @i_a__2(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: jg .LBB15_2 ; CHECK-NEXT: jg .LBB15_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %esi, %eax ; CHECK-NEXT: cmovll %eax, %esi
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %esi
; CHECK-NEXT: movl %eax, %esi
; CHECK-NEXT: .LBB15_2: # %return ; CHECK-NEXT: .LBB15_2: # %return
; CHECK-NEXT: movslq %esi, %rax ; CHECK-NEXT: movslq %esi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
@ -516,9 +507,8 @@ define i64 @i_a__1(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: .LBB16_1: # %if.end ; CHECK-NEXT: .LBB16_1: # %if.end
; CHECK-NEXT: cmpl $-1, %edi ; CHECK-NEXT: cmpl $-1, %edi
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %esi, %eax ; CHECK-NEXT: cmovll %eax, %esi
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %esi
; CHECK-NEXT: movl %eax, %esi
; CHECK-NEXT: movslq %esi, %rax ; CHECK-NEXT: movslq %esi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
@ -547,9 +537,8 @@ define i64 @i_a_0(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: retq ; CHECK-NEXT: retq
; CHECK-NEXT: .LBB17_1: # %if.end ; CHECK-NEXT: .LBB17_1: # %if.end
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %esi, %eax ; CHECK-NEXT: cmovsl %eax, %esi
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %esi
; CHECK-NEXT: movl %eax, %esi
; CHECK-NEXT: movslq %esi, %rax ; CHECK-NEXT: movslq %esi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
entry: entry:
@ -574,10 +563,10 @@ define i64 @i_a_1(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: cmpl $1, %edi ; CHECK-NEXT: cmpl $1, %edi
; CHECK-NEXT: jg .LBB18_2 ; CHECK-NEXT: jg .LBB18_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: testl %edi, %edi
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %esi, %eax ; CHECK-NEXT: cmovlel %eax, %esi
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %esi
; CHECK-NEXT: movl %eax, %esi
; CHECK-NEXT: .LBB18_2: # %return ; CHECK-NEXT: .LBB18_2: # %return
; CHECK-NEXT: movslq %esi, %rax ; CHECK-NEXT: movslq %esi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
@ -604,9 +593,8 @@ define i64 @i_a_2(i32 signext %a, i32 signext %b) {
; CHECK-NEXT: jg .LBB19_2 ; CHECK-NEXT: jg .LBB19_2
; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: cmovel %esi, %eax ; CHECK-NEXT: cmovll %eax, %esi
; CHECK-NEXT: imull %edi, %eax ; CHECK-NEXT: imull %edi, %esi
; CHECK-NEXT: movl %eax, %esi
; CHECK-NEXT: .LBB19_2: # %return ; CHECK-NEXT: .LBB19_2: # %return
; CHECK-NEXT: movslq %esi, %rax ; CHECK-NEXT: movslq %esi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq