-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[ValueTracking] Support assume in entry block without DT #109264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
isValidAssumeForContext() handles a couple of trivial cases even if no dominator tree is available. This adds one more for the case where there is an assume in the entry block, and a use in some other block. The entry block always dominates all blocks. As having context instruction but not having DT is pretty rare, there is not much impact. Only test change is in assume-builder.ll, where less redundant assumes are generated. Having the special case is useful for an upcoming change though.
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-transforms Author: Nikita Popov (nikic) ChangesisValidAssumeForContext() handles a couple of trivial cases even if no dominator tree is available. This adds one more for the case where there is an assume in the entry block, and a use in some other block. The entry block always dominates all blocks. As having context instruction but not having DT is fairly rare, there is not much impact. Only test change is in assume-builder.ll, where less redundant assumes are generated. I've found having this special case is useful for an upcoming change though. Full diff: https://github.com/llvm/llvm-project/pull/109264.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index ba3ba7cc98136d..56eb3f99b39d2c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -528,7 +528,8 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv,
if (DT) {
if (DT->dominates(Inv, CxtI))
return true;
- } else if (Inv->getParent() == CxtI->getParent()->getSinglePredecessor()) {
+ } else if (Inv->getParent() == CxtI->getParent()->getSinglePredecessor() ||
+ Inv->getParent()->isEntryBlock()) {
// We don't have a DT, but this trivially dominates.
return true;
}
diff --git a/llvm/test/Transforms/Util/assume-builder.ll b/llvm/test/Transforms/Util/assume-builder.ll
index 47629a22e36965..98ff2a4827d61b 100644
--- a/llvm/test/Transforms/Util/assume-builder.ll
+++ b/llvm/test/Transforms/Util/assume-builder.ll
@@ -567,15 +567,13 @@ define dso_local i32 @_Z6squarePi(ptr %P, ptr %P1, i1 %cond) {
; BASIC-NEXT: store i32 0, ptr [[P1]], align 4
; BASIC-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
; BASIC: B:
-; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 8) ]
+; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; BASIC-NEXT: store i32 0, ptr [[P]], align 8
-; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
; BASIC-NEXT: store i32 0, ptr [[P1]], align 8
; BASIC-NEXT: br label [[C]]
; BASIC: C:
-; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 32) ]
+; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
; BASIC-NEXT: store i32 0, ptr [[P]], align 32
-; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 4) ]
; BASIC-NEXT: store i32 0, ptr [[P1]], align 4
; BASIC-NEXT: ret i32 0
;
@@ -593,15 +591,13 @@ define dso_local i32 @_Z6squarePi(ptr %P, ptr %P1, i1 %cond) {
; ALL-NEXT: store i32 0, ptr [[P1]], align 4
; ALL-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
; ALL: B:
-; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 8) ]
+; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; ALL-NEXT: store i32 0, ptr [[P]], align 8
-; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
; ALL-NEXT: store i32 0, ptr [[P1]], align 8
; ALL-NEXT: br label [[C]]
; ALL: C:
-; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 32) ]
+; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
; ALL-NEXT: store i32 0, ptr [[P]], align 32
-; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 4) ]
; ALL-NEXT: store i32 0, ptr [[P1]], align 4
; ALL-NEXT: ret i32 0
;
@@ -619,15 +615,13 @@ define dso_local i32 @_Z6squarePi(ptr %P, ptr %P1, i1 %cond) {
; WITH-AC-NEXT: store i32 0, ptr [[P1]], align 4
; WITH-AC-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
; WITH-AC: B:
-; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 8) ]
+; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; WITH-AC-NEXT: store i32 0, ptr [[P]], align 8
-; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
; WITH-AC-NEXT: store i32 0, ptr [[P1]], align 8
; WITH-AC-NEXT: br label [[C]]
; WITH-AC: C:
-; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 32) ]
+; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
; WITH-AC-NEXT: store i32 0, ptr [[P]], align 32
-; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 4) ]
; WITH-AC-NEXT: store i32 0, ptr [[P1]], align 4
; WITH-AC-NEXT: ret i32 0
;
@@ -667,12 +661,12 @@ define dso_local i32 @_Z6squarePi(ptr %P, ptr %P1, i1 %cond) {
; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P1]], align 4
; FULL-SIMPLIFY-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
; FULL-SIMPLIFY: B:
-; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "ignore"(ptr undef, i64 4), "ignore"(ptr undef), "align"(ptr [[P]], i64 8) ]
+; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P]], align 8
; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P1]], align 8
; FULL-SIMPLIFY-NEXT: br label [[C]]
; FULL-SIMPLIFY: C:
-; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "ignore"(ptr undef, i64 4), "ignore"(ptr undef), "align"(ptr [[P]], i64 32) ]
+; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P]], align 32
; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P1]], align 4
; FULL-SIMPLIFY-NEXT: ret i32 0
@@ -830,10 +824,10 @@ define dso_local i32 @terminator(ptr %P) personality ptr @__gxx_personality_v0 {
; BASIC-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
; BASIC-NEXT: bb:
; BASIC-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
-; BASIC-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
+; BASIC-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
; BASIC: Catch:
; BASIC-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
-; BASIC-NEXT: catch ptr null
+; BASIC-NEXT: catch ptr null
; BASIC-NEXT: br label [[EXIT]]
; BASIC: Exit:
; BASIC-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
@@ -843,10 +837,10 @@ define dso_local i32 @terminator(ptr %P) personality ptr @__gxx_personality_v0 {
; ALL-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
; ALL-NEXT: bb:
; ALL-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
-; ALL-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
+; ALL-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
; ALL: Catch:
; ALL-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
-; ALL-NEXT: catch ptr null
+; ALL-NEXT: catch ptr null
; ALL-NEXT: br label [[EXIT]]
; ALL: Exit:
; ALL-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
@@ -856,10 +850,10 @@ define dso_local i32 @terminator(ptr %P) personality ptr @__gxx_personality_v0 {
; WITH-AC-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
; WITH-AC-NEXT: bb:
; WITH-AC-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
-; WITH-AC-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
+; WITH-AC-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
; WITH-AC: Catch:
; WITH-AC-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
-; WITH-AC-NEXT: catch ptr null
+; WITH-AC-NEXT: catch ptr null
; WITH-AC-NEXT: br label [[EXIT]]
; WITH-AC: Exit:
; WITH-AC-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
@@ -869,10 +863,10 @@ define dso_local i32 @terminator(ptr %P) personality ptr @__gxx_personality_v0 {
; CROSS-BLOCK-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
; CROSS-BLOCK-NEXT: bb:
; CROSS-BLOCK-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
-; CROSS-BLOCK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
+; CROSS-BLOCK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
; CROSS-BLOCK: Catch:
; CROSS-BLOCK-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
-; CROSS-BLOCK-NEXT: catch ptr null
+; CROSS-BLOCK-NEXT: catch ptr null
; CROSS-BLOCK-NEXT: br label [[EXIT]]
; CROSS-BLOCK: Exit:
; CROSS-BLOCK-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
@@ -882,10 +876,10 @@ define dso_local i32 @terminator(ptr %P) personality ptr @__gxx_personality_v0 {
; FULL-SIMPLIFY-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
; FULL-SIMPLIFY-NEXT: bb:
; FULL-SIMPLIFY-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
-; FULL-SIMPLIFY-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
+; FULL-SIMPLIFY-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
; FULL-SIMPLIFY: Catch:
; FULL-SIMPLIFY-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
-; FULL-SIMPLIFY-NEXT: catch ptr null
+; FULL-SIMPLIFY-NEXT: catch ptr null
; FULL-SIMPLIFY-NEXT: br label [[EXIT]]
; FULL-SIMPLIFY: Exit:
; FULL-SIMPLIFY-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
isValidAssumeForContext() handles a couple of trivial cases even if no dominator tree is available. This adds one more for the case where there is an assume in the entry block, and a use in some other block. The entry block always dominates all blocks. As having context instruction but not having DT is fairly rare, there is not much impact. Only test change is in assume-builder.ll, where less redundant assumes are generated. I've found having this special case is useful for an upcoming change though.
isValidAssumeForContext() handles a couple of trivial cases even if no dominator tree is available. This adds one more for the case where there is an assume in the entry block, and a use in some other block. The entry block always dominates all blocks.
As having context instruction but not having DT is fairly rare, there is not much impact. Only test change is in assume-builder.ll, where less redundant assumes are generated. I've found having this special case is useful for an upcoming change though.