Skip to content
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

[ValueTracking] Support assume in entry block without DT #109264

Merged
merged 1 commit into from
Sep 19, 2024

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Sep 19, 2024

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 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.
@llvmbot
Copy link
Collaborator

llvmbot commented Sep 19, 2024

@llvm/pr-subscribers-llvm-analysis

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/109264.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/ValueTracking.cpp (+2-1)
  • (modified) llvm/test/Transforms/Util/assume-builder.ll (+18-24)
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]] ]

Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@nikic nikic merged commit dd599e9 into llvm:main Sep 19, 2024
11 checks passed
@nikic nikic deleted the assume-entry-block branch September 19, 2024 12:24
tmsri pushed a commit to tmsri/llvm-project that referenced this pull request Sep 19, 2024
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants