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,11 @@ 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. + if (DivInst->hasPoisonGeneratingFlags()) + 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: [[DOTFROZEN:%.*]] = freeze i8 [[TMP1:%.*]] ; CHECK-NEXT: [[DOTFROZEN1:%.*]] = freeze i8 [[TMP2:%.*]] -; CHECK-NEXT: [[TMP4:%.*]] = udiv exact i8 [[DOTFROZEN]], [[DOTFROZEN1]] +; CHECK-NEXT: [[TMP4:%.*]] = udiv i8 [[DOTFROZEN]], [[DOTFROZEN1]] ; CHECK-NEXT: [[TMP5:%.*]] = mul i8 [[TMP4]], [[DOTFROZEN1]] ; CHECK-NEXT: [[DOTDECOMPOSED:%.*]] = sub i8 [[DOTFROZEN]], [[TMP5]] ; CHECK-NEXT: store i8 [[DOTDECOMPOSED]], ptr [[TMP0:%.*]], align 1