Skip to content

Commit 669511a

Browse files
committed
[InstCombine] Allow min/max in constant BOp min/max folding
1 parent db9c88c commit 669511a

File tree

2 files changed

+40
-26
lines changed

2 files changed

+40
-26
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,7 +1822,6 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
18221822
static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
18231823
Value *FalseVal,
18241824
IRBuilderBase &Builder) {
1825-
BinaryOperator *BOp;
18261825
Constant *C1, *C2, *C3;
18271826
Value *X;
18281827
CmpPredicate Predicate;
@@ -1838,30 +1837,48 @@ static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
18381837
Predicate = ICmpInst::getInversePredicate(Predicate);
18391838
}
18401839

1841-
if (!match(TrueVal, m_BinOp(BOp)) || !match(FalseVal, m_Constant(C3)))
1840+
if (!match(FalseVal, m_Constant(C3)) || !TrueVal->hasOneUse())
18421841
return nullptr;
18431842

1844-
unsigned Opcode = BOp->getOpcode();
1843+
bool IsIntrinsic;
1844+
unsigned Opcode;
1845+
if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(TrueVal)) {
1846+
Opcode = BOp->getOpcode();
1847+
IsIntrinsic = false;
18451848

1846-
// This fold causes some regressions and is primarily intended for
1847-
// add and sub. So we early exit for div and rem to minimize the
1848-
// regressions.
1849-
if (Instruction::isIntDivRem(Opcode))
1850-
return nullptr;
1849+
// This fold causes some regressions and is primarily intended for
1850+
// add and sub. So we early exit for div and rem to minimize the
1851+
// regressions.
1852+
if (Instruction::isIntDivRem(Opcode))
1853+
return nullptr;
18511854

1852-
if (!match(BOp, m_OneUse(m_BinOp(m_Specific(X), m_Constant(C2)))))
1855+
if (!match(BOp, m_BinOp(m_Specific(X), m_Constant(C2))))
1856+
return nullptr;
1857+
1858+
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(TrueVal)) {
1859+
if (!match(II, m_MaxOrMin(m_Specific(X), m_Constant(C2))))
1860+
return nullptr;
1861+
Opcode = II->getIntrinsicID();
1862+
IsIntrinsic = true;
1863+
} else {
18531864
return nullptr;
1865+
}
18541866

18551867
Value *RHS;
18561868
SelectPatternFlavor SPF;
1857-
const DataLayout &DL = BOp->getDataLayout();
1869+
const DataLayout &DL = Cmp->getDataLayout();
18581870
auto Flipped = getFlippedStrictnessPredicateAndConstant(Predicate, C1);
18591871

1860-
if (C3 == ConstantFoldBinaryOpOperands(Opcode, C1, C2, DL)) {
1872+
auto FoldBinaryOpOrIntrinsic = [&](Constant *LHS, Constant *RHS) {
1873+
return IsIntrinsic ? ConstantFoldBinaryIntrinsic(Opcode, LHS, RHS,
1874+
LHS->getType(), nullptr)
1875+
: ConstantFoldBinaryOpOperands(Opcode, LHS, RHS, DL);
1876+
};
1877+
1878+
if (C3 == FoldBinaryOpOrIntrinsic(C1, C2)) {
18611879
SPF = getSelectPattern(Predicate).Flavor;
18621880
RHS = C1;
1863-
} else if (Flipped && C3 == ConstantFoldBinaryOpOperands(
1864-
Opcode, Flipped->second, C2, DL)) {
1881+
} else if (Flipped && C3 == FoldBinaryOpOrIntrinsic(Flipped->second, C2)) {
18651882
SPF = getSelectPattern(Flipped->first).Flavor;
18661883
RHS = Flipped->second;
18671884
} else {
@@ -1870,7 +1887,9 @@ static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
18701887

18711888
Intrinsic::ID IntrinsicID = getMinMaxIntrinsic(SPF);
18721889
Value *Intrinsic = Builder.CreateBinaryIntrinsic(IntrinsicID, X, RHS);
1873-
return Builder.CreateBinOp(BOp->getOpcode(), Intrinsic, C2);
1890+
return IsIntrinsic ? Builder.CreateBinaryIntrinsic(Opcode, Intrinsic, C2)
1891+
: Builder.CreateBinOp(Instruction::BinaryOps(Opcode),
1892+
Intrinsic, C2);
18741893
}
18751894

18761895
/// Visit a SelectInst that has an ICmpInst as its first operand.

llvm/test/Transforms/InstCombine/canonicalize-const-to-bop.ll

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,7 @@ define i8 @sub_const_on_lhs_negative(i8 %x) {
403403
define i8 @smin_ugt(i8 %x) {
404404
; CHECK-LABEL: define i8 @smin_ugt(
405405
; CHECK-SAME: i8 [[X:%.*]]) {
406-
; CHECK-NEXT: [[SMIN:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 50)
407-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X]], 100
408-
; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 50, i8 [[SMIN]]
406+
; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 50)
409407
; CHECK-NEXT: ret i8 [[S]]
410408
;
411409
%smin = call i8 @llvm.smin.i8(i8 %x, i8 50)
@@ -417,9 +415,8 @@ define i8 @smin_ugt(i8 %x) {
417415
define i8 @smax_ugt(i8 %x) {
418416
; CHECK-LABEL: define i8 @smax_ugt(
419417
; CHECK-SAME: i8 [[X:%.*]]) {
420-
; CHECK-NEXT: [[SMAX:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 50)
421-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X]], 100
422-
; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 100, i8 [[SMAX]]
418+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 100)
419+
; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.smax.i8(i8 [[TMP1]], i8 50)
423420
; CHECK-NEXT: ret i8 [[S]]
424421
;
425422
%smax = call i8 @llvm.smax.i8(i8 %x, i8 50)
@@ -431,9 +428,8 @@ define i8 @smax_ugt(i8 %x) {
431428
define i8 @umin_slt(i8 %x) {
432429
; CHECK-LABEL: define i8 @umin_slt(
433430
; CHECK-SAME: i8 [[X:%.*]]) {
434-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X]], 0
435-
; CHECK-NEXT: [[UMIN:%.*]] = tail call i8 @llvm.umin.i8(i8 [[X]], i8 100)
436-
; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 0, i8 [[UMIN]]
431+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 0)
432+
; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.umin.i8(i8 [[TMP1]], i8 100)
437433
; CHECK-NEXT: ret i8 [[S]]
438434
;
439435
%cmp = icmp slt i8 %x, 0
@@ -445,9 +441,8 @@ define i8 @umin_slt(i8 %x) {
445441
define i8 @umax_sgt(i8 %x) {
446442
; CHECK-LABEL: define i8 @umax_sgt(
447443
; CHECK-SAME: i8 [[X:%.*]]) {
448-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X]], 100
449-
; CHECK-NEXT: [[UMAX:%.*]] = tail call i8 @llvm.umax.i8(i8 [[X]], i8 50)
450-
; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 100, i8 [[UMAX]]
444+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 100)
445+
; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.umax.i8(i8 [[TMP1]], i8 50)
451446
; CHECK-NEXT: ret i8 [[S]]
452447
;
453448
%cmp = icmp sgt i8 %x, 100

0 commit comments

Comments
 (0)