[llvm] 2647547 - Re-revert "[ValueTracking] Use knownbits interface for determining if `div`/`rem` are safe to speculate"
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Tue May 9 17:11:45 PDT 2023
Author: Noah Goldstein
Date: 2023-05-09T19:11:21-05:00
New Revision: 2647547ee44f509a34ff9709b63bd7603ca59f5d
URL: https://github.com/llvm/llvm-project/commit/2647547ee44f509a34ff9709b63bd7603ca59f5d
DIFF: https://github.com/llvm/llvm-project/commit/2647547ee44f509a34ff9709b63bd7603ca59f5d.diff
LOG: Re-revert "[ValueTracking] Use knownbits interface for determining if `div`/`rem` are safe to speculate"
Seems to be causing a bug in CorrelatedValuePropegation. Reverting
while the issue is investigated.
This reverts commit 6c667abf3294d61e4fbe1238e1755c79f7547f1b.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/LICM/speculate-div.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 6f6a16c8ee4c0..385fe427d3108 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6099,34 +6099,31 @@ bool llvm::isSafeToSpeculativelyExecuteWithOpcode(
default:
return true;
case Instruction::UDiv:
- case Instruction::URem:
+ case Instruction::URem: {
+ // x / y is undefined if y == 0.
+ const APInt *V;
+ if (match(Inst->getOperand(1), m_APInt(V)))
+ return *V != 0;
+ return false;
+ }
case Instruction::SDiv:
case Instruction::SRem: {
- // x / y is undefined if y == 0 or y is poison.
- const DataLayout &DL = Inst->getModule()->getDataLayout();
- if (!isGuaranteedNotToBePoison(Inst->getOperand(1), AC, CtxI, DT) ||
- !isKnownNonZero(Inst->getOperand(1), DL, /*Depth*/ 0, AC, CtxI, DT))
+ // x / y is undefined if y == 0 or x == INT_MIN and y == -1
+ const APInt *Numerator, *Denominator;
+ if (!match(Inst->getOperand(1), m_APInt(Denominator)))
+ return false;
+ // We cannot hoist this division if the denominator is 0.
+ if (*Denominator == 0)
return false;
-
- // Unsigned case only needs to avoid denominator == 0 or poison.
- if (Opcode == Instruction::UDiv || Opcode == Instruction::URem)
- return true;
-
- // x s/ y is also undefined if x == INT_MIN and y == -1
- KnownBits KnownDenominator =
- computeKnownBits(Inst->getOperand(1), DL, /*Depth*/ 0, AC, CtxI, DT);
-
// It's safe to hoist if the denominator is not 0 or -1.
- if (!KnownDenominator.Zero.isZero())
+ if (!Denominator->isAllOnes())
return true;
-
- // At this point denominator may be -1. It is safe to hoist as
- // long we know that the numerator is neither poison nor INT_MIN.
- if (!isGuaranteedNotToBePoison(Inst->getOperand(0), AC, CtxI, DT))
- return false;
- KnownBits KnownNumerator =
- computeKnownBits(Inst->getOperand(0), DL, /*Depth*/ 0, AC, CtxI, DT);
- return !KnownNumerator.getSignedMinValue().isMinSignedValue();
+ // At this point we know that the denominator is -1. It is safe to hoist as
+ // long we know that the numerator is not INT_MIN.
+ if (match(Inst->getOperand(0), m_APInt(Numerator)))
+ return !Numerator->isMinSignedValue();
+ // The numerator *might* be MinSignedValue.
+ return false;
}
case Instruction::Load: {
const LoadInst *LI = dyn_cast<LoadInst>(Inst);
diff --git a/llvm/test/Transforms/LICM/speculate-div.ll b/llvm/test/Transforms/LICM/speculate-div.ll
index fde63e43d0164..50e755ef7083e 100644
--- a/llvm/test/Transforms/LICM/speculate-div.ll
+++ b/llvm/test/Transforms/LICM/speculate-div.ll
@@ -4,7 +4,7 @@
declare void @maythrow()
declare void @use(i16)
-define void @sdiv_not_ok(i16 %n, i16 noundef %xx) {
+define void @sdiv_not_ok(i16 %n, i16 %xx) {
; CHECK-LABEL: @sdiv_not_ok(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[X:%.*]] = or i16 [[XX:%.*]], 1
@@ -25,7 +25,7 @@ loop:
br label %loop
}
-define void @srem_not_ok2(i16 %nn, i16 noundef %x) {
+define void @srem_not_ok2(i16 %nn, i16 %x) {
; CHECK-LABEL: @srem_not_ok2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[N:%.*]] = and i16 [[NN:%.*]], 1323
@@ -46,15 +46,15 @@ loop:
br label %loop
}
-define void @sdiv_ok(i16 %n, i16 noundef %xx) {
+define void @sdiv_ok(i16 %n, i16 %xx) {
; CHECK-LABEL: @sdiv_ok(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XO:%.*]] = or i16 [[XX:%.*]], 1
; CHECK-NEXT: [[X:%.*]] = and i16 [[XO]], 123
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i16 [[N:%.*]], [[X]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: call void @maythrow()
+; CHECK-NEXT: [[DIV:%.*]] = sdiv i16 [[N:%.*]], [[X]]
; CHECK-NEXT: call void @use(i16 [[DIV]])
; CHECK-NEXT: br label [[LOOP]]
;
@@ -69,15 +69,15 @@ loop:
br label %loop
}
-define void @srem_ok2(i16 noundef %nn, i16 noundef %xx) {
+define void @srem_ok2(i16 %nn, i16 %xx) {
; CHECK-LABEL: @srem_ok2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[N:%.*]] = and i16 [[NN:%.*]], 123
; CHECK-NEXT: [[X:%.*]] = or i16 [[XX:%.*]], 1
-; CHECK-NEXT: [[DIV:%.*]] = srem i16 [[N]], [[X]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: call void @maythrow()
+; CHECK-NEXT: [[DIV:%.*]] = srem i16 [[N]], [[X]]
; CHECK-NEXT: call void @use(i16 [[DIV]])
; CHECK-NEXT: br label [[LOOP]]
;
@@ -92,53 +92,7 @@ loop:
br label %loop
}
-define void @sdiv_not_ok3_maybe_poison_denum(i16 noundef %nn, i16 %xx) {
-; CHECK-LABEL: @sdiv_not_ok3_maybe_poison_denum(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[N:%.*]] = and i16 [[NN:%.*]], 123
-; CHECK-NEXT: [[X:%.*]] = or i16 [[XX:%.*]], 1
-; CHECK-NEXT: br label [[LOOP:%.*]]
-; CHECK: loop:
-; CHECK-NEXT: call void @maythrow()
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i16 [[N]], [[X]]
-; CHECK-NEXT: call void @use(i16 [[DIV]])
-; CHECK-NEXT: br label [[LOOP]]
-;
-entry:
- %n = and i16 %nn, 123
- %x = or i16 %xx, 1
- br label %loop
-loop:
- call void @maythrow()
- %div = sdiv i16 %n, %x
- call void @use(i16 %div)
- br label %loop
-}
-
-define void @sdiv_not_ok3_maybe_poison_num(i16 %nn, i16 noundef %xx) {
-; CHECK-LABEL: @sdiv_not_ok3_maybe_poison_num(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[N:%.*]] = and i16 [[NN:%.*]], 123
-; CHECK-NEXT: [[X:%.*]] = or i16 [[XX:%.*]], 1
-; CHECK-NEXT: br label [[LOOP:%.*]]
-; CHECK: loop:
-; CHECK-NEXT: call void @maythrow()
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i16 [[N]], [[X]]
-; CHECK-NEXT: call void @use(i16 [[DIV]])
-; CHECK-NEXT: br label [[LOOP]]
-;
-entry:
- %n = and i16 %nn, 123
- %x = or i16 %xx, 1
- br label %loop
-loop:
- call void @maythrow()
- %div = sdiv i16 %n, %x
- call void @use(i16 %div)
- br label %loop
-}
-
-define void @udiv_not_ok(i16 %n, i16 noundef %xx) {
+define void @udiv_not_ok(i16 %n, i16 %xx) {
; CHECK-LABEL: @udiv_not_ok(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[X:%.*]] = xor i16 [[XX:%.*]], 1
@@ -159,31 +113,10 @@ loop:
br label %loop
}
-define void @udiv_ok(i16 %n, i16 noundef %xx) {
+define void @udiv_ok(i16 %n, i16 %xx) {
; CHECK-LABEL: @udiv_ok(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[X:%.*]] = or i16 [[XX:%.*]], 1
-; CHECK-NEXT: [[DIV:%.*]] = udiv i16 [[N:%.*]], [[X]]
-; CHECK-NEXT: br label [[LOOP:%.*]]
-; CHECK: loop:
-; CHECK-NEXT: call void @maythrow()
-; CHECK-NEXT: call void @use(i16 [[DIV]])
-; CHECK-NEXT: br label [[LOOP]]
-;
-entry:
- %x = or i16 %xx, 1
- br label %loop
-loop:
- call void @maythrow()
- %div = udiv i16 %n, %x
- call void @use(i16 %div)
- br label %loop
-}
-
-define void @urem_not_ok_maybe_poison(i16 %n, i16 %xx) {
-; CHECK-LABEL: @urem_not_ok_maybe_poison(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[X:%.*]] = or i16 [[XX:%.*]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: call void @maythrow()
More information about the llvm-commits
mailing list