Skip to content

Commit 603b736

Browse files
committed
Addressed review comments.
1 parent 7c20ea3 commit 603b736

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
@@ -3633,42 +3633,56 @@ static bool hasAffectedValue(Value *V, SmallPtrSetImpl<Value *> &Affected,
36333633
return false;
36343634
}
36353635

3636-
static Value *foldSelectAddConstant(SelectInst &SI,
3637-
InstCombiner::BuilderTy &Builder) {
3638-
Value *Cmp;
3639-
Instruction *FAdd;
3640-
ConstantFP *C;
3641-
3642-
// select((fcmp OGT/OLT, X, 0), (fadd X, C), C) => fadd((select (fcmp OGT/OLT,
3643-
// X, 0), X, 0), C)
3636+
// This transformation enables the possibility of transforming fcmp + sel into
3637+
// a fmaxnum/fminnum intrinsic.
3638+
static Value *foldSelectIntoAddConstant(SelectInst &SI,
3639+
InstCombiner::BuilderTy &Builder) {
3640+
// Do this transformation only when select instruction gives NaN and NSZ
3641+
// guarantee.
3642+
auto *SIFOp = dyn_cast<FPMathOperator>(&SI);
3643+
if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
3644+
return nullptr;
36443645

3645-
// This transformation enables the possibility of transforming fcmp + sel into
3646-
// a fmax/fmin.
3646+
// select((fcmp Pred, X, 0), (fadd X, C), C)
3647+
// => fadd((select (fcmp Pred, X, 0), X, 0), C)
3648+
//
3649+
// Pred := OGT, OGE, OLT, OLE, UGT, UGE, ULT, and ULE
3650+
Instruction *FAdd;
3651+
Constant *C;
3652+
Value *X, *Z;
3653+
CmpInst::Predicate Pred;
36473654

3648-
// OneUse check for `Cmp` is necessary because it makes sure that other
3655+
// Note: OneUse check for `Cmp` is necessary because it makes sure that other
36493656
// InstCombine folds don't undo this transformation and cause an infinite
36503657
// loop.
3651-
if (match(&SI, m_Select(m_OneUse(m_Value(Cmp)), m_OneUse(m_Instruction(FAdd)),
3652-
m_ConstantFP(C))) ||
3653-
match(&SI, m_Select(m_OneUse(m_Value(Cmp)), m_ConstantFP(C),
3654-
m_OneUse(m_Instruction(FAdd))))) {
3655-
Value *X;
3656-
CmpInst::Predicate Pred;
3657-
if (!match(Cmp, m_FCmp(Pred, m_Value(X), m_AnyZeroFP())))
3658+
if (match(&SI, m_Select(m_OneUse(m_FCmp(Pred, m_Value(X), m_Value(Z))),
3659+
m_OneUse(m_Instruction(FAdd)), m_Constant(C))) ||
3660+
match(&SI, m_Select(m_OneUse(m_FCmp(Pred, m_Value(X), m_Value(Z))),
3661+
m_Constant(C), m_OneUse(m_Instruction(FAdd))))) {
3662+
if (!match(Z, m_AnyZeroFP()))
36583663
return nullptr;
36593664

3660-
if (Pred != CmpInst::FCMP_OGT && Pred != CmpInst::FCMP_OLT)
3665+
// Only these Predicates can be transformed into fmaxnum/fminnum intrinsic.
3666+
switch (Pred) {
3667+
default:
36613668
return nullptr;
3669+
case FCmpInst::FCMP_OGT:
3670+
case FCmpInst::FCMP_OGE:
3671+
case FCmpInst::FCMP_OLT:
3672+
case FCmpInst::FCMP_OLE:
3673+
case FCmpInst::FCMP_UGT:
3674+
case FCmpInst::FCMP_UGE:
3675+
case FCmpInst::FCMP_ULT:
3676+
case FCmpInst::FCMP_ULE:
3677+
break;
3678+
}
36623679

36633680
if (!match(FAdd, m_FAdd(m_Specific(X), m_Specific(C))))
36643681
return nullptr;
36653682

3666-
FastMathFlags FMF = FAdd->getFastMathFlags();
3667-
FMF |= SI.getFastMathFlags();
3668-
3669-
Value *NewSelect = Builder.CreateSelect(
3670-
Cmp, X, ConstantFP::getZero(C->getType()), SI.getName() + ".new", &SI);
3671-
cast<Instruction>(NewSelect)->setFastMathFlags(FMF);
3683+
Value *NewSelect = Builder.CreateSelect(SI.getCondition(), X, Z,
3684+
SI.getName() + ".new", &SI);
3685+
cast<Instruction>(NewSelect)->setFastMathFlags(SI.getFastMathFlags());
36723686

36733687
Value *NewFAdd =
36743688
Builder.CreateFAddFMF(NewSelect, C, FAdd, FAdd->getName() + ".new");
@@ -4074,9 +4088,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
40744088
if (Value *V = foldRoundUpIntegerWithPow2Alignment(SI, Builder))
40754089
return replaceInstUsesWith(SI, V);
40764090

4077-
if (Value *V = foldSelectAddConstant(SI, Builder)) {
4091+
if (Value *V = foldSelectIntoAddConstant(SI, Builder))
40784092
return replaceInstUsesWith(SI, V);
4079-
}
40804093

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

0 commit comments

Comments
 (0)