diff options
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
| -rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 75 |
1 files changed, 16 insertions, 59 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 05e8f5761c13..8567a0504f54 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -81,48 +81,6 @@ static Value *simplifyInstructionWithOperands(Instruction *I, const SimplifyQuery &SQ, unsigned MaxRecurse); -static Value *foldSelectWithBinaryOp(Value *Cond, Value *TrueVal, - Value *FalseVal) { - BinaryOperator::BinaryOps BinOpCode; - if (auto *BO = dyn_cast<BinaryOperator>(Cond)) - BinOpCode = BO->getOpcode(); - else - return nullptr; - - CmpInst::Predicate ExpectedPred; - if (BinOpCode == BinaryOperator::Or) { - ExpectedPred = ICmpInst::ICMP_NE; - } else if (BinOpCode == BinaryOperator::And) { - ExpectedPred = ICmpInst::ICMP_EQ; - } else - return nullptr; - - // %A = icmp eq %TV, %FV - // %B = icmp eq %X, %Y (and one of these is a select operand) - // %C = and %A, %B - // %D = select %C, %TV, %FV - // --> - // %FV - - // %A = icmp ne %TV, %FV - // %B = icmp ne %X, %Y (and one of these is a select operand) - // %C = or %A, %B - // %D = select %C, %TV, %FV - // --> - // %TV - Value *X, *Y; - if (!match(Cond, - m_c_BinOp(m_c_SpecificICmp(ExpectedPred, m_Specific(TrueVal), - m_Specific(FalseVal)), - m_SpecificICmp(ExpectedPred, m_Value(X), m_Value(Y))))) - return nullptr; - - if (X == TrueVal || X == FalseVal || Y == TrueVal || Y == FalseVal) - return BinOpCode == BinaryOperator::Or ? TrueVal : FalseVal; - - return nullptr; -} - /// For a boolean type or a vector of boolean type, return false or a vector /// with every element false. static Constant *getFalse(Type *Ty) { return ConstantInt::getFalse(Ty); } @@ -1542,12 +1500,12 @@ static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp, const SimplifyQuery &Q) { Value *X, *Y; - ICmpInst::Predicate EqPred; + CmpPredicate EqPred; if (!match(ZeroICmp, m_ICmp(EqPred, m_Value(Y), m_Zero())) || !ICmpInst::isEquality(EqPred)) return nullptr; - ICmpInst::Predicate UnsignedPred; + CmpPredicate UnsignedPred; Value *A, *B; // Y = (A - B); @@ -1686,7 +1644,7 @@ static Value *simplifyAndOrOfICmpsWithConstants(ICmpInst *Cmp0, ICmpInst *Cmp1, static Value *simplifyAndOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1, const InstrInfoQuery &IIQ) { // (icmp (add V, C0), C1) & (icmp V, C0) - ICmpInst::Predicate Pred0, Pred1; + CmpPredicate Pred0, Pred1; const APInt *C0, *C1; Value *V; if (!match(Op0, m_ICmp(Pred0, m_Add(m_Value(V), m_APInt(C0)), m_APInt(C1)))) @@ -1733,7 +1691,7 @@ static Value *simplifyAndOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1, /// Try to simplify and/or of icmp with ctpop intrinsic. static Value *simplifyAndOrOfICmpsWithCtpop(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd) { - ICmpInst::Predicate Pred0, Pred1; + CmpPredicate Pred0, Pred1; Value *X; const APInt *C; if (!match(Cmp0, m_ICmp(Pred0, m_Intrinsic<Intrinsic::ctpop>(m_Value(X)), @@ -1777,7 +1735,7 @@ static Value *simplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1, static Value *simplifyOrOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1, const InstrInfoQuery &IIQ) { // (icmp (add V, C0), C1) | (icmp V, C0) - ICmpInst::Predicate Pred0, Pred1; + CmpPredicate Pred0, Pred1; const APInt *C0, *C1; Value *V; if (!match(Op0, m_ICmp(Pred0, m_Add(m_Value(V), m_APInt(C0)), m_APInt(C1)))) @@ -1933,7 +1891,7 @@ static Value *simplifyAndOrWithICmpEq(unsigned Opcode, Value *Op0, Value *Op1, unsigned MaxRecurse) { assert((Opcode == Instruction::And || Opcode == Instruction::Or) && "Must be and/or"); - ICmpInst::Predicate Pred; + CmpPredicate Pred; Value *A, *B; if (!match(Op0, m_ICmp(Pred, m_Value(A), m_Value(B))) || !ICmpInst::isEquality(Pred)) @@ -4387,11 +4345,14 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, if (auto *BO = dyn_cast<BinaryOperator>(I)) { unsigned Opcode = BO->getOpcode(); // id op x -> x, x op id -> x - if (NewOps[0] == ConstantExpr::getBinOpIdentity(Opcode, I->getType())) - return NewOps[1]; - if (NewOps[1] == ConstantExpr::getBinOpIdentity(Opcode, I->getType(), - /* RHS */ true)) - return NewOps[0]; + // Exclude floats, because x op id may produce a different NaN value. + if (!BO->getType()->isFPOrFPVectorTy()) { + if (NewOps[0] == ConstantExpr::getBinOpIdentity(Opcode, I->getType())) + return NewOps[1]; + if (NewOps[1] == ConstantExpr::getBinOpIdentity(Opcode, I->getType(), + /* RHS */ true)) + return NewOps[0]; + } // x & x -> x, x | x -> x if ((Opcode == Instruction::And || Opcode == Instruction::Or) && @@ -4656,7 +4617,7 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q, unsigned MaxRecurse) { - ICmpInst::Predicate Pred; + CmpPredicate Pred; Value *CmpLHS, *CmpRHS; if (!match(CondVal, m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)))) return nullptr; @@ -4780,7 +4741,7 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal, static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F, const SimplifyQuery &Q, unsigned MaxRecurse) { - FCmpInst::Predicate Pred; + CmpPredicate Pred; Value *CmpLHS, *CmpRHS; if (!match(Cond, m_FCmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)))) return nullptr; @@ -4994,9 +4955,6 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, if (Value *V = simplifySelectWithFCmp(Cond, TrueVal, FalseVal, Q, MaxRecurse)) return V; - if (Value *V = foldSelectWithBinaryOp(Cond, TrueVal, FalseVal)) - return V; - std::optional<bool> Imp = isImpliedByDomCondition(Cond, Q.CxtI, Q.DL); if (Imp) return *Imp ? TrueVal : FalseVal; @@ -7186,7 +7144,6 @@ static Value *simplifyInstructionWithOperands(Instruction *I, NewOps[1], I->getFastMathFlags(), Q, MaxRecurse); case Instruction::Select: return simplifySelectInst(NewOps[0], NewOps[1], NewOps[2], Q, MaxRecurse); - break; case Instruction::GetElementPtr: { auto *GEPI = cast<GetElementPtrInst>(I); return simplifyGEPInst(GEPI->getSourceElementType(), NewOps[0], |
