[llvm] [InstSimplify][InstCombine][ConstantFold] Move vector div/rem by zero fold to InstCombine (PR #114280)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 30 17:14:40 PDT 2024
================
@@ -1158,29 +1158,39 @@ static Value *foldIDivShl(BinaryOperator &I, InstCombiner::BuilderTy &Builder) {
return nullptr;
}
-/// This function implements the transforms common to both integer division
-/// instructions (udiv and sdiv). It is called by the visitors to those integer
-/// division instructions.
-/// Common integer divide transforms
-Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
- if (Instruction *Phi = foldBinopWithPhiOperands(I))
- return Phi;
-
+/// Common integer divide/remainder transforms
+Instruction *InstCombinerImpl::commonIDivRemTransforms(BinaryOperator &I) {
+ assert(I.isIntDivRem() && "Unexpected instruction");
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
- bool IsSigned = I.getOpcode() == Instruction::SDiv;
Type *Ty = I.getType();
+ // If any element of a constant divisor fixed width vector is zero or undef
+ // the behavior is undefined and we can fold the whole op to poison.
+ if (auto *Op1C = dyn_cast<Constant>(Op1)) {
+ if (auto *VTy = dyn_cast<FixedVectorType>(Ty)) {
+ unsigned NumElts = VTy->getNumElements();
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *Elt = Op1C->getAggregateElement(i);
+ if (Elt && (Elt->isNullValue() || isa<UndefValue>(Elt)))
+ return replaceInstUsesWith(I, PoisonValue::get(Ty));
----------------
dtcxzyw wrote:
It doesn't block `udiv <i32 42, i32 -7> <i32 0, i32 1> -> poison` if the udiv is indeed an instruction. It just blocks this transform when threading udiv over selects.
https://github.com/llvm/llvm-project/pull/114280
More information about the llvm-commits
mailing list