Skip to content

Commit 6596e2e

Browse files
committed
Addressed review comments.
1 parent 4bcc510 commit 6596e2e

File tree

2 files changed

+548
-146
lines changed

2 files changed

+548
-146
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3661,42 +3661,56 @@ static bool hasAffectedValue(Value *V, SmallPtrSetImpl<Value *> &Affected,
36613661
return false;
36623662
}
36633663

3664-
static Value *foldSelectAddConstant(SelectInst &SI,
3665-
InstCombiner::BuilderTy &Builder) {
3666-
Value *Cmp;
3667-
Instruction *FAdd;
3668-
ConstantFP *C;
3669-
3670-
// select((fcmp OGT/OLT, X, 0), (fadd X, C), C) => fadd((select (fcmp OGT/OLT,
3671-
// X, 0), X, 0), C)
3664+
// This transformation enables the possibility of transforming fcmp + sel into
3665+
// a fmaxnum/fminnum intrinsic.
3666+
static Value *foldSelectIntoAddConstant(SelectInst &SI,
3667+
InstCombiner::BuilderTy &Builder) {
3668+
// Do this transformation only when select instruction gives NaN and NSZ
3669+
// guarantee.
3670+
auto *SIFOp = dyn_cast<FPMathOperator>(&SI);
3671+
if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
3672+
return nullptr;
36723673

3673-
// This transformation enables the possibility of transforming fcmp + sel into
3674-
// a fmax/fmin.
3674+
// select((fcmp Pred, X, 0), (fadd X, C), C)
3675+
// => fadd((select (fcmp Pred, X, 0), X, 0), C)
3676+
//
3677+
// Pred := OGT, OGE, OLT, OLE, UGT, UGE, ULT, and ULE
3678+
Instruction *FAdd;
3679+
Constant *C;
3680+
Value *X, *Z;
3681+
CmpInst::Predicate Pred;
36753682

3676-
// OneUse check for `Cmp` is necessary because it makes sure that other
3683+
// Note: OneUse check for `Cmp` is necessary because it makes sure that other
36773684
// InstCombine folds don't undo this transformation and cause an infinite
36783685
// loop.
3679-
if (match(&SI, m_Select(m_OneUse(m_Value(Cmp)), m_OneUse(m_Instruction(FAdd)),
3680-
m_ConstantFP(C))) ||
3681-
match(&SI, m_Select(m_OneUse(m_Value(Cmp)), m_ConstantFP(C),
3682-
m_OneUse(m_Instruction(FAdd))))) {
3683-
Value *X;
3684-
CmpInst::Predicate Pred;
3685-
if (!match(Cmp, m_FCmp(Pred, m_Value(X), m_AnyZeroFP())))
3686+
if (match(&SI, m_Select(m_OneUse(m_FCmp(Pred, m_Value(X), m_Value(Z))),
3687+
m_OneUse(m_Instruction(FAdd)), m_Constant(C))) ||
3688+
match(&SI, m_Select(m_OneUse(m_FCmp(Pred, m_Value(X), m_Value(Z))),
3689+
m_Constant(C), m_OneUse(m_Instruction(FAdd))))) {
3690+
if (!match(Z, m_AnyZeroFP()))
36863691
return nullptr;
36873692

3688-
if (Pred != CmpInst::FCMP_OGT && Pred != CmpInst::FCMP_OLT)
3693+
// Only these Predicates can be transformed into fmaxnum/fminnum intrinsic.
3694+
switch (Pred) {
3695+
default:
36893696
return nullptr;
3697+
case FCmpInst::FCMP_OGT:
3698+
case FCmpInst::FCMP_OGE:
3699+
case FCmpInst::FCMP_OLT:
3700+
case FCmpInst::FCMP_OLE:
3701+
case FCmpInst::FCMP_UGT:
3702+
case FCmpInst::FCMP_UGE:
3703+
case FCmpInst::FCMP_ULT:
3704+
case FCmpInst::FCMP_ULE:
3705+
break;
3706+
}
36903707

36913708
if (!match(FAdd, m_FAdd(m_Specific(X), m_Specific(C))))
36923709
return nullptr;
36933710

3694-
FastMathFlags FMF = FAdd->getFastMathFlags();
3695-
FMF |= SI.getFastMathFlags();
3696-
3697-
Value *NewSelect = Builder.CreateSelect(
3698-
Cmp, X, ConstantFP::getZero(C->getType()), SI.getName() + ".new", &SI);
3699-
cast<Instruction>(NewSelect)->setFastMathFlags(FMF);
3711+
Value *NewSelect = Builder.CreateSelect(SI.getCondition(), X, Z,
3712+
SI.getName() + ".new", &SI);
3713+
cast<Instruction>(NewSelect)->setFastMathFlags(SI.getFastMathFlags());
37003714

37013715
Value *NewFAdd =
37023716
Builder.CreateFAddFMF(NewSelect, C, FAdd, FAdd->getName() + ".new");
@@ -4102,9 +4116,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
41024116
if (Value *V = foldRoundUpIntegerWithPow2Alignment(SI, Builder))
41034117
return replaceInstUsesWith(SI, V);
41044118

4105-
if (Value *V = foldSelectAddConstant(SI, Builder)) {
4119+
if (Value *V = foldSelectIntoAddConstant(SI, Builder))
41064120
return replaceInstUsesWith(SI, V);
4107-
}
41084121

41094122
// select(mask, mload(,,mask,0), 0) -> mload(,,mask,0)
41104123
// Load inst is intentionally not checked for hasOneUse()

0 commit comments

Comments
 (0)