Skip to content

Instantly share code, notes, and snippets.

@nikic
Created February 19, 2021 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/10e0538a45093258e43851e57e5180f1 to your computer and use it in GitHub Desktop.
Save nikic/10e0538a45093258e43851e57e5180f1 to your computer and use it in GitHub Desktop.
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index edf165c1a582..a556986b80d5 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -536,7 +536,29 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv,
// feeding the assume is trivially true, thus causing the removal of
// the assume).
- if (Inv->getParent() == CxtI->getParent()) {
+ auto GuaranteedToExecuteInvFrom = [&](BasicBlock::const_iterator I) {
+ // We limit the scan distance between the context instruction and the assume
+ // to avoid a compile-time explosion. This limit is chosen arbitrarily, so
+ // it can be adjusted if needed (could be turned into a cl::opt).
+ unsigned ScanLimit = 15;
+ for (BasicBlock::const_iterator IE(Inv); I != IE; ++I)
+ if (!isGuaranteedToTransferExecutionToSuccessor(&*I) || --ScanLimit == 0)
+ return false;
+ return true;
+ };
+
+ const BasicBlock *InvBB = Inv->getParent();
+ if (!CxtI) {
+ // If there is no context instruction, assume the start of the entry block
+ // as context, and see whether the assume is guaranteed reachable from
+ // there.
+ if (InvBB != &InvBB->getParent()->getEntryBlock())
+ return false;
+
+ return GuaranteedToExecuteInvFrom(InvBB->begin());
+ }
+
+ if (InvBB == CxtI->getParent()) {
// If Inv and CtxI are in the same block, check if the assume (Inv) is first
// in the BB.
if (Inv->comesBefore(CxtI))
@@ -551,22 +573,15 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv,
// The context comes first, but they're both in the same block.
// Make sure there is nothing in between that might interrupt
// the control flow, not even CxtI itself.
- // We limit the scan distance between the assume and its context instruction
- // to avoid a compile-time explosion. This limit is chosen arbitrarily, so
- // it can be adjusted if needed (could be turned into a cl::opt).
- unsigned ScanLimit = 15;
- for (BasicBlock::const_iterator I(CxtI), IE(Inv); I != IE; ++I)
- if (!isGuaranteedToTransferExecutionToSuccessor(&*I) || --ScanLimit == 0)
- return false;
-
- return !isEphemeralValueOf(Inv, CxtI);
+ return GuaranteedToExecuteInvFrom(CxtI->getIterator()) &&
+ !isEphemeralValueOf(Inv, CxtI);
}
// Inv and CxtI are in different blocks.
if (DT) {
if (DT->dominates(Inv, CxtI))
return true;
- } else if (Inv->getParent() == CxtI->getParent()->getSinglePredecessor()) {
+ } else if (InvBB == CxtI->getParent()->getSinglePredecessor()) {
// We don't have a DT, but this trivially dominates.
return true;
}
@@ -639,9 +654,7 @@ static bool isKnownNonZeroFromAssume(const Value *V, const Query &Q) {
static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
unsigned Depth, const Query &Q) {
- // Use of assumptions is context-sensitive. If we don't have a context, we
- // cannot use them!
- if (!Q.AC || !Q.CxtI)
+ if (!Q.AC)
return;
unsigned BitWidth = Known.getBitWidth();
@@ -661,8 +674,6 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
if (!AssumeVH)
continue;
CallInst *I = cast<CallInst>(AssumeVH);
- assert(I->getParent()->getParent() == Q.CxtI->getParent()->getParent() &&
- "Got assumption for the wrong function!");
if (Q.isExcluded(I))
continue;
diff --git a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
index 48dc484635a6..2a81d5f92d40 100644
--- a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
+++ b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
@@ -454,15 +454,15 @@ define void @test_guard_and_assume(i32* nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_and_assume'
; CHECK-NEXT: Classifying expressions for: @test_guard_and_assume
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
-; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count)<nsw> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
-; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count)<nuw><nsw> + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_and_assume
-; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
+; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)<nsw>
; CHECK-NEXT: Loop %loop: max backedge-taken count is 3
-; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %count)
+; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %count)<nsw>
; CHECK-NEXT: Predicates:
; CHECK: Loop %loop: Trip multiple is 1
;
diff --git a/llvm/test/Analysis/ScalarEvolution/ranges.ll b/llvm/test/Analysis/ScalarEvolution/ranges.ll
index d38e522cdb8a..78b10b17f707 100644
--- a/llvm/test/Analysis/ScalarEvolution/ranges.ll
+++ b/llvm/test/Analysis/ScalarEvolution/ranges.ll
@@ -38,7 +38,7 @@ define i32 @lshr(i32 %a) {
; CHECK-LABEL: 'lshr'
; CHECK-NEXT: Classifying expressions for: @lshr
; CHECK-NEXT: %res = lshr i32 %a, 31
-; CHECK-NEXT: --> (%a /u -2147483648) U: [0,2) S: [0,2)
+; CHECK-NEXT: --> (%a /u -2147483648) U: [0,1) S: [0,1)
; CHECK-NEXT: Determining loop execution counts for: @lshr
;
%pos = icmp sge i32 %a, 0
@@ -52,7 +52,7 @@ define i32 @udiv(i32 %a) {
; CHECK-LABEL: 'udiv'
; CHECK-NEXT: Classifying expressions for: @udiv
; CHECK-NEXT: %res = udiv i32 %a, -2147483648
-; CHECK-NEXT: --> (%a /u -2147483648) U: [0,2) S: [0,2)
+; CHECK-NEXT: --> (%a /u -2147483648) U: [0,1) S: [0,1)
; CHECK-NEXT: Determining loop execution counts for: @udiv
;
%pos = icmp sge i32 %a, 0
@@ -65,7 +65,7 @@ define i64 @sext(i32 %a) {
; CHECK-LABEL: 'sext'
; CHECK-NEXT: Classifying expressions for: @sext
; CHECK-NEXT: %res = sext i32 %a to i64
-; CHECK-NEXT: --> (sext i32 %a to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
+; CHECK-NEXT: --> (zext i32 %a to i64) U: [0,2147483648) S: [0,2147483648)
; CHECK-NEXT: Determining loop execution counts for: @sext
;
%pos = icmp sge i32 %a, 0
@@ -78,7 +78,7 @@ define i64 @zext(i32 %a) {
; CHECK-LABEL: 'zext'
; CHECK-NEXT: Classifying expressions for: @zext
; CHECK-NEXT: %res = zext i32 %a to i64
-; CHECK-NEXT: --> (zext i32 %a to i64) U: [0,4294967296) S: [0,4294967296)
+; CHECK-NEXT: --> (zext i32 %a to i64) U: [0,2147483648) S: [0,2147483648)
; CHECK-NEXT: Determining loop execution counts for: @zext
;
%pos = icmp sge i32 %a, 0
diff --git a/llvm/test/Transforms/SimplifyCFG/pr46638.ll b/llvm/test/Transforms/SimplifyCFG/pr46638.ll
index bdc2848239a3..0ad72ff0a0f2 100644
--- a/llvm/test/Transforms/SimplifyCFG/pr46638.ll
+++ b/llvm/test/Transforms/SimplifyCFG/pr46638.ll
@@ -13,9 +13,7 @@ define void @pr46638(i1 %c, i32 %x) {
; CHECK-NEXT: call void @dummy(i32 [[EXT]])
; CHECK-NEXT: ret void
; CHECK: true2.critedge:
-; CHECK-NEXT: [[CMP2_C:%.*]] = icmp sgt i32 [[X]], 0
-; CHECK-NEXT: [[EXT_C:%.*]] = zext i1 [[CMP2_C]] to i32
-; CHECK-NEXT: call void @dummy(i32 [[EXT_C]])
+; CHECK-NEXT: call void @dummy(i32 0)
; CHECK-NEXT: call void @dummy(i32 2)
; CHECK-NEXT: ret void
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment