diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2024-01-03 18:04:11 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-19 21:24:24 +0000 |
| commit | 0c85e2760f6b5016c16d29f8c2f63f3ba2cf5298 (patch) | |
| tree | d6c9033fa7ca2f632ddc81d371ef3faf921652db /contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp | |
| parent | 92d4d6f1f60e5d9cb2c7e0dd5d632987e54741e8 (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp b/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp index 5beac5547d65..78a833476334 100644 --- a/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp @@ -1189,14 +1189,26 @@ static Value *simplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, if (Value *V = simplifyDivRem(Opcode, Op0, Op1, Q, MaxRecurse)) return V; - // If this is an exact divide by a constant, then the dividend (Op0) must have - // at least as many trailing zeros as the divisor to divide evenly. If it has - // less trailing zeros, then the result must be poison. const APInt *DivC; - if (IsExact && match(Op1, m_APInt(DivC)) && DivC->countr_zero()) { - KnownBits KnownOp0 = computeKnownBits(Op0, /* Depth */ 0, Q); - if (KnownOp0.countMaxTrailingZeros() < DivC->countr_zero()) - return PoisonValue::get(Op0->getType()); + if (IsExact && match(Op1, m_APInt(DivC))) { + // If this is an exact divide by a constant, then the dividend (Op0) must + // have at least as many trailing zeros as the divisor to divide evenly. If + // it has less trailing zeros, then the result must be poison. + if (DivC->countr_zero()) { + KnownBits KnownOp0 = computeKnownBits(Op0, /* Depth */ 0, Q); + if (KnownOp0.countMaxTrailingZeros() < DivC->countr_zero()) + return PoisonValue::get(Op0->getType()); + } + + // udiv exact (mul nsw X, C), C --> X + // sdiv exact (mul nuw X, C), C --> X + // where C is not a power of 2. + Value *X; + if (!DivC->isPowerOf2() && + (Opcode == Instruction::UDiv + ? match(Op0, m_NSWMul(m_Value(X), m_Specific(Op1))) + : match(Op0, m_NUWMul(m_Value(X), m_Specific(Op1))))) + return X; } return nullptr; @@ -4857,14 +4869,12 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, // select ?, poison, X -> X // select ?, undef, X -> X if (isa<PoisonValue>(TrueVal) || - (Q.isUndefValue(TrueVal) && - isGuaranteedNotToBePoison(FalseVal, Q.AC, Q.CxtI, Q.DT))) + (Q.isUndefValue(TrueVal) && impliesPoison(FalseVal, Cond))) return FalseVal; // select ?, X, poison -> X // select ?, X, undef -> X if (isa<PoisonValue>(FalseVal) || - (Q.isUndefValue(FalseVal) && - isGuaranteedNotToBePoison(TrueVal, Q.AC, Q.CxtI, Q.DT))) + (Q.isUndefValue(FalseVal) && impliesPoison(TrueVal, Cond))) return TrueVal; // Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC'' |
