diff --git a/llvm/lib/Transforms/Scalar/DivRemPairs.cpp b/llvm/lib/Transforms/Scalar/DivRemPairs.cpp --- a/llvm/lib/Transforms/Scalar/DivRemPairs.cpp +++ b/llvm/lib/Transforms/Scalar/DivRemPairs.cpp @@ -371,6 +371,10 @@ 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 diff --git a/llvm/test/Transforms/DivRemPairs/AArch64/div-rem-pairs.ll b/llvm/test/Transforms/DivRemPairs/AArch64/div-rem-pairs.ll --- a/llvm/test/Transforms/DivRemPairs/AArch64/div-rem-pairs.ll +++ b/llvm/test/Transforms/DivRemPairs/AArch64/div-rem-pairs.ll @@ -5,7 +5,7 @@ ; 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