[llvm] 8325189 - [NFC][InstCombine] Refactor InstCombinerImpl::foldSelectIntoOp
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 13 02:37:13 PDT 2022
Author: David Sherwood
Date: 2022-06-13T10:37:07+01:00
New Revision: 83251896d74bf0df85259b2e65b701aa14355705
URL: https://github.com/llvm/llvm-project/commit/83251896d74bf0df85259b2e65b701aa14355705
DIFF: https://github.com/llvm/llvm-project/commit/83251896d74bf0df85259b2e65b701aa14355705.diff
LOG: [NFC][InstCombine] Refactor InstCombinerImpl::foldSelectIntoOp
Introduce a lambda function so that we remove a lot of code
duplication.
Differential Revision: https://reviews.llvm.org/D127493
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index c18e8f856b2f..f49e74b28801 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -439,79 +439,56 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
Value *FalseVal) {
// See the comment above GetSelectFoldableOperands for a description of the
// transformation we are doing here.
- if (auto *TVI = dyn_cast<BinaryOperator>(TrueVal)) {
- if (TVI->hasOneUse() && !isa<Constant>(FalseVal)) {
- if (unsigned SFO = getSelectFoldableOperands(TVI)) {
- unsigned OpToFold = 0;
- if ((SFO & 1) && FalseVal == TVI->getOperand(0)) {
- OpToFold = 1;
- } else if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
- OpToFold = 2;
- }
-
- if (OpToFold) {
- FastMathFlags FMF;
- if (isa<FPMathOperator>(&SI))
- FMF = SI.getFastMathFlags();
- Constant *C = ConstantExpr::getBinOpIdentity(
- TVI->getOpcode(), TVI->getType(), true, FMF.noSignedZeros());
- Value *OOp = TVI->getOperand(2-OpToFold);
- // Avoid creating select between 2 constants unless it's selecting
- // between 0, 1 and -1.
- const APInt *OOpC;
- bool OOpIsAPInt = match(OOp, m_APInt(OOpC));
- if (!isa<Constant>(OOp) ||
- (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) {
- Value *NewSel = Builder.CreateSelect(SI.getCondition(), OOp, C);
+ auto TryFoldSelectIntoOp = [&](SelectInst &SI, Value *TrueVal,
+ Value *FalseVal,
+ bool Swapped) -> Instruction * {
+ if (auto *TVI = dyn_cast<BinaryOperator>(TrueVal)) {
+ if (TVI->hasOneUse() && !isa<Constant>(FalseVal)) {
+ if (unsigned SFO = getSelectFoldableOperands(TVI)) {
+ unsigned OpToFold = 0;
+ if ((SFO & 1) && FalseVal == TVI->getOperand(0))
+ OpToFold = 1;
+ else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
+ OpToFold = 2;
+
+ if (OpToFold) {
+ FastMathFlags FMF;
+ // TODO: We probably ought to revisit cases where the select and FP
+ // instructions have
diff erent flags and add tests to ensure the
+ // behaviour is correct.
if (isa<FPMathOperator>(&SI))
- cast<Instruction>(NewSel)->setFastMathFlags(FMF);
- NewSel->takeName(TVI);
- BinaryOperator *BO = BinaryOperator::Create(TVI->getOpcode(),
- FalseVal, NewSel);
- BO->copyIRFlags(TVI);
- return BO;
+ FMF = SI.getFastMathFlags();
+ Constant *C = ConstantExpr::getBinOpIdentity(
+ TVI->getOpcode(), TVI->getType(), true, FMF.noSignedZeros());
+ Value *OOp = TVI->getOperand(2 - OpToFold);
+ // Avoid creating select between 2 constants unless it's selecting
+ // between 0, 1 and -1.
+ const APInt *OOpC;
+ bool OOpIsAPInt = match(OOp, m_APInt(OOpC));
+ if (!isa<Constant>(OOp) ||
+ (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) {
+ Value *NewSel = Builder.CreateSelect(
+ SI.getCondition(), Swapped ? C : OOp, Swapped ? OOp : C);
+ if (isa<FPMathOperator>(&SI))
+ cast<Instruction>(NewSel)->setFastMathFlags(FMF);
+ NewSel->takeName(TVI);
+ BinaryOperator *BO =
+ BinaryOperator::Create(TVI->getOpcode(), FalseVal, NewSel);
+ BO->copyIRFlags(TVI);
+ return BO;
+ }
}
}
}
}
- }
+ return nullptr;
+ };
- if (auto *FVI = dyn_cast<BinaryOperator>(FalseVal)) {
- if (FVI->hasOneUse() && !isa<Constant>(TrueVal)) {
- if (unsigned SFO = getSelectFoldableOperands(FVI)) {
- unsigned OpToFold = 0;
- if ((SFO & 1) && TrueVal == FVI->getOperand(0)) {
- OpToFold = 1;
- } else if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
- OpToFold = 2;
- }
+ if (Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal, false))
+ return R;
- if (OpToFold) {
- FastMathFlags FMF;
- if (isa<FPMathOperator>(&SI))
- FMF = SI.getFastMathFlags();
- Constant *C = ConstantExpr::getBinOpIdentity(
- FVI->getOpcode(), FVI->getType(), true, FMF.noSignedZeros());
- Value *OOp = FVI->getOperand(2-OpToFold);
- // Avoid creating select between 2 constants unless it's selecting
- // between 0, 1 and -1.
- const APInt *OOpC;
- bool OOpIsAPInt = match(OOp, m_APInt(OOpC));
- if (!isa<Constant>(OOp) ||
- (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) {
- Value *NewSel = Builder.CreateSelect(SI.getCondition(), C, OOp);
- if (isa<FPMathOperator>(&SI))
- cast<Instruction>(NewSel)->setFastMathFlags(FMF);
- NewSel->takeName(FVI);
- BinaryOperator *BO = BinaryOperator::Create(FVI->getOpcode(),
- TrueVal, NewSel);
- BO->copyIRFlags(FVI);
- return BO;
- }
- }
- }
- }
- }
+ if (Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal, true))
+ return R;
return nullptr;
}
More information about the llvm-commits
mailing list