[PATCH] D150353: [CVP] Don't introduce zero after truncating when narrowUDivOrSDiv

luxufan via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 11 03:32:55 PDT 2023


StephenFan updated this revision to Diff 521247.
StephenFan added a comment.

Delete blank line


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150353/new/

https://reviews.llvm.org/D150353

Files:
  llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
  llvm/test/Transforms/CorrelatedValuePropagation/udiv.ll
  llvm/test/Transforms/CorrelatedValuePropagation/urem.ll


Index: llvm/test/Transforms/CorrelatedValuePropagation/urem.ll
===================================================================
--- llvm/test/Transforms/CorrelatedValuePropagation/urem.ll
+++ llvm/test/Transforms/CorrelatedValuePropagation/urem.ll
@@ -394,4 +394,21 @@
   ret void
 }
 
+define i32 @udiv_do_not_truncate(i32 noundef %call, i32 %v) {
+; CHECK-LABEL: @udiv_do_not_truncate(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL_NON_NULL:%.*]] = or i32 [[CALL:%.*]], 1
+; CHECK-NEXT:    [[DIV:%.*]] = urem i32 8192, [[CALL_NON_NULL]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[CALL_NON_NULL]], 8192
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], i32 1, i32 [[DIV]]
+; CHECK-NEXT:    ret i32 [[SELECT]]
+;
+entry:
+  %call_non_null = or i32 %call, 1
+  %div = urem i32 8192, %call_non_null
+  %cmp = icmp ugt i32 %call_non_null, 8192
+  %select = select i1 %cmp, i32 1, i32 %div
+  ret i32 %select
+}
+
 declare void @use(i1)
Index: llvm/test/Transforms/CorrelatedValuePropagation/udiv.ll
===================================================================
--- llvm/test/Transforms/CorrelatedValuePropagation/udiv.ll
+++ llvm/test/Transforms/CorrelatedValuePropagation/udiv.ll
@@ -99,3 +99,4 @@
 exit:
   ret void
 }
+
Index: llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -785,8 +785,10 @@
 
 /// Try to shrink a udiv/urem's width down to the smallest power of two that's
 /// sufficient to contain its operands.
-static bool narrowUDivOrURem(BinaryOperator *Instr, const ConstantRange &XCR,
-                             const ConstantRange &YCR) {
+static bool narrowUDivOrURem(BinaryOperator *Instr,
+                             const ConstantRange &XCRAtUse,
+                             const ConstantRange &YCRAtUse,
+                             const ConstantRange &YCRAtDef) {
   assert(Instr->getOpcode() == Instruction::UDiv ||
          Instr->getOpcode() == Instruction::URem);
   assert(!Instr->getType()->isVectorTy());
@@ -796,7 +798,8 @@
 
   // What is the smallest bit width that can accommodate the entire value ranges
   // of both of the operands?
-  unsigned MaxActiveBits = std::max(XCR.getActiveBits(), YCR.getActiveBits());
+  unsigned MaxActiveBits =
+      std::max(XCRAtUse.getActiveBits(), YCRAtUse.getActiveBits());
   // Don't shrink below 8 bits wide.
   unsigned NewWidth = std::max<unsigned>(PowerOf2Ceil(MaxActiveBits), 8);
 
@@ -805,6 +808,13 @@
   if (NewWidth >= Instr->getType()->getIntegerBitWidth())
     return false;
 
+  // For divisor, if the constant range computed at define point does not
+  // contain zero, then we should ensure the constant range after truncating
+  // also does not contain zero. Otherwise we may introduce an UB.
+  if (!YCRAtDef.contains(APInt::getZero(YCRAtDef.getBitWidth())) &&
+      YCRAtDef.truncate(NewWidth).contains(APInt::getZero(NewWidth)))
+    return false;
+
   ++NumUDivURemsNarrowed;
   IRBuilder<> B{Instr};
   auto *TruncTy = Type::getIntNTy(Instr->getContext(), NewWidth);
@@ -829,12 +839,13 @@
   if (Instr->getType()->isVectorTy())
     return false;
 
-  ConstantRange XCR = LVI->getConstantRangeAtUse(Instr->getOperandUse(0));
-  ConstantRange YCR = LVI->getConstantRangeAtUse(Instr->getOperandUse(1));
-  if (expandUDivOrURem(Instr, XCR, YCR))
+  ConstantRange YCRAtDef = LVI->getConstantRange(Instr->getOperand(1), Instr);
+  ConstantRange XCRAtUse = LVI->getConstantRangeAtUse(Instr->getOperandUse(0));
+  ConstantRange YCRAtUse = LVI->getConstantRangeAtUse(Instr->getOperandUse(1));
+  if (expandUDivOrURem(Instr, XCRAtUse, YCRAtUse))
     return true;
 
-  return narrowUDivOrURem(Instr, XCR, YCR);
+  return narrowUDivOrURem(Instr, XCRAtUse, YCRAtUse, YCRAtDef);
 }
 
 static bool processSRem(BinaryOperator *SDI, const ConstantRange &LCR,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150353.521247.patch
Type: text/x-patch
Size: 3970 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230511/44c5783f/attachment.bin>


More information about the llvm-commits mailing list