[llvm] [InstSimplify][InstCombine][ConstantFold] Move vector div/rem by zero fold to InstCombine (PR #114280)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 31 02:53:30 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));
----------------
antoniofrighetto wrote:

> We can convert it into an immediate UB here. But it's not worth the effort.

Why would we want to convert it into immediate UB? poison looks correct here to me. Actually, could we get rid of the undef (when checking for the aggregate), while at it, at this moment for this specific instance?

https://github.com/llvm/llvm-project/pull/114280


More information about the llvm-commits mailing list