Skip to content

Commit 926e610

Browse files
committed
[InstCombine] Extend foldSelectInstWithICmpConst to handle minmax
1 parent c1645ad commit 926e610

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,26 +1771,38 @@ static Value *foldSelectInstWithICmpConst(SelectInst &SI, ICmpInst *ICI,
17711771
return Builder.CreateBinaryIntrinsic(Intrinsic::smin, V, TVal);
17721772
}
17731773

1774-
BinaryOperator *BO;
1774+
// Fold icmp(X) ? f(X) : C to f(X) when f(X) is guaranteed to be equal to C
1775+
// for all X in the exact range of the inverse predicate.
1776+
Instruction *Op;
17751777
const APInt *C;
17761778
CmpInst::Predicate CPred;
1777-
if (match(&SI, m_Select(m_Specific(ICI), m_APInt(C), m_BinOp(BO))))
1779+
if (match(&SI, m_Select(m_Specific(ICI), m_APInt(C), m_Instruction(Op))))
17781780
CPred = ICI->getPredicate();
1779-
else if (match(&SI, m_Select(m_Specific(ICI), m_BinOp(BO), m_APInt(C))))
1781+
else if (match(&SI, m_Select(m_Specific(ICI), m_Instruction(Op), m_APInt(C))))
17801782
CPred = ICI->getInversePredicate();
17811783
else
17821784
return nullptr;
17831785

1784-
const APInt *BinOpC;
1785-
if (!match(BO, m_BinOp(m_Specific(V), m_APInt(BinOpC))))
1786-
return nullptr;
1787-
1788-
ConstantRange R = ConstantRange::makeExactICmpRegion(CPred, *CmpC)
1789-
.binaryOp(BO->getOpcode(), *BinOpC);
1790-
if (R == *C) {
1791-
BO->dropPoisonGeneratingFlags();
1792-
return BO;
1786+
ConstantRange InvDomCR = ConstantRange::makeExactICmpRegion(CPred, *CmpC);
1787+
const APInt *OpC;
1788+
if (match(Op, m_BinOp(m_Specific(V), m_APInt(OpC)))) {
1789+
ConstantRange R = InvDomCR.binaryOp(
1790+
static_cast<Instruction::BinaryOps>(Op->getOpcode()), *OpC);
1791+
if (R == *C) {
1792+
Op->dropPoisonGeneratingFlags();
1793+
return Op;
1794+
}
1795+
}
1796+
if (auto *MMI = dyn_cast<MinMaxIntrinsic>(Op);
1797+
MMI && MMI->getLHS() == V && match(MMI->getRHS(), m_APInt(OpC))) {
1798+
ConstantRange R = ConstantRange::intrinsic(MMI->getIntrinsicID(),
1799+
{InvDomCR, ConstantRange(*OpC)});
1800+
if (R == *C) {
1801+
MMI->dropPoisonGeneratingAnnotations();
1802+
return MMI;
1803+
}
17931804
}
1805+
17941806
return nullptr;
17951807
}
17961808

llvm/test/Transforms/InstCombine/select-min-max.ll

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,8 @@ define i8 @not_smin_swap(i8 %i41, i8 %i43) {
304304

305305
define i8 @sel_umin_constant(i8 %x) {
306306
; CHECK-LABEL: @sel_umin_constant(
307-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
308-
; CHECK-NEXT: [[UMIN:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 16)
309-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[UMIN]], i8 16
310-
; CHECK-NEXT: ret i8 [[SEL]]
307+
; CHECK-NEXT: [[UMIN:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 16)
308+
; CHECK-NEXT: ret i8 [[UMIN]]
311309
;
312310
%cmp = icmp sgt i8 %x, -1
313311
%umin = call i8 @llvm.umin.i8(i8 %x, i8 16)
@@ -317,9 +315,7 @@ define i8 @sel_umin_constant(i8 %x) {
317315

318316
define i8 @sel_constant_smax_with_range_attr(i8 %x) {
319317
; CHECK-LABEL: @sel_constant_smax_with_range_attr(
320-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
321-
; CHECK-NEXT: [[SMAX:%.*]] = call range(i8 8, 16) i8 @llvm.smax.i8(i8 [[X]], i8 16)
322-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 16, i8 [[SMAX]]
318+
; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 16)
323319
; CHECK-NEXT: ret i8 [[SEL]]
324320
;
325321
%cmp = icmp slt i8 %x, 0

0 commit comments

Comments
 (0)