diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index ddf5882f901df..5ea30560093d5 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -466,44 +466,44 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal, auto TryFoldSelectIntoOp = [&](SelectInst &SI, Value *TrueVal, Value *FalseVal, bool Swapped) -> Instruction * { - if (auto *TVI = dyn_cast(TrueVal)) { - if (TVI->hasOneUse() && !isa(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 different flags and add tests to ensure the - // behaviour is correct. - if (isa(&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(OOp) || - (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) { - Value *NewSel = Builder.CreateSelect( - SI.getCondition(), Swapped ? C : OOp, Swapped ? OOp : C); - if (isa(&SI)) - cast(NewSel)->setFastMathFlags(FMF); - NewSel->takeName(TVI); - BinaryOperator *BO = - BinaryOperator::Create(TVI->getOpcode(), FalseVal, NewSel); - BO->copyIRFlags(TVI); - return BO; - } - } - } - } + auto *TVI = dyn_cast(TrueVal); + if (!TVI || !TVI->hasOneUse() || isa(FalseVal)) + return nullptr; + + 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) + return nullptr; + + // TODO: We probably ought to revisit cases where the select and FP + // instructions have different flags and add tests to ensure the + // behaviour is correct. + FastMathFlags FMF; + if (isa(&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(OOp) || + (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) { + Value *NewSel = Builder.CreateSelect(SI.getCondition(), Swapped ? C : OOp, + Swapped ? OOp : C); + if (isa(&SI)) + cast(NewSel)->setFastMathFlags(FMF); + NewSel->takeName(TVI); + BinaryOperator *BO = + BinaryOperator::Create(TVI->getOpcode(), FalseVal, NewSel); + BO->copyIRFlags(TVI); + return BO; } return nullptr; };