[DivRemPairs] Strip division's poison generating flag
authorJuneyoung Lee <aqjune@gmail.com>
Sat, 18 Feb 2023 20:43:26 +0000 (20:43 +0000)
committerJuneyoung Lee <aqjune@gmail.com>
Sat, 18 Feb 2023 21:00:55 +0000 (21:00 +0000)
Given this transformation: X % Y -> X - (X / Y) * Y

This patch strips off the poison-generating flag of X / Y such as exact, because it may make the optimized form result poison whereas X % Y does not.

The issue was reported here: https://github.com/llvm/llvm-project/issues/60748

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D144333

llvm/lib/Transforms/Scalar/DivRemPairs.cpp
llvm/test/Transforms/DivRemPairs/AArch64/div-rem-pairs.ll

index 3039516..2b06e8f 100644 (file)
@@ -371,6 +371,10 @@ static bool optimizeDivRem(Function &F, const TargetTransformInfo &TTI,
       Mul->insertAfter(RemInst);
       Sub->insertAfter(Mul);
 
+      // If DivInst has the exact flag, remove it. Otherwise this optimization
+      // may replace a well-defined value 'X % Y' with poison.
+      DivInst->dropPoisonGeneratingFlags();
+
       // If X can be undef, X should be frozen first.
       // For example, let's assume that Y = 1 & X = undef:
       //   %div = sdiv undef, 1 // %div = undef
index f7e0eaa..b787f21 100644 (file)
@@ -5,7 +5,7 @@ define i8 @f(ptr %p, i8 %x, i8 %y) {
 ; CHECK-LABEL: @f(
 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X:%.*]]
 ; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i8 [[Y:%.*]]
-; CHECK-NEXT:    [[XDIVY:%.*]] = udiv exact i8 [[X_FROZEN]], [[Y_FROZEN]]
+; CHECK-NEXT:    [[XDIVY:%.*]] = udiv i8 [[X_FROZEN]], [[Y_FROZEN]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[XDIVY]], [[Y_FROZEN]]
 ; CHECK-NEXT:    [[XMODY_DECOMPOSED:%.*]] = sub i8 [[X_FROZEN]], [[TMP1]]
 ; CHECK-NEXT:    store i8 [[XMODY_DECOMPOSED]], ptr [[P:%.*]], align 1