Skip to content

[MoveAutoInit] Ignore unreachable basicblocks and handle catchswitch #78232

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

Merged
merged 1 commit into from
Jan 16, 2024

Conversation

XChy
Copy link
Member

@XChy XChy commented Jan 16, 2024

Fixes #78049
This patch has done:

  • Ignore unreachable predecessors when looking for nearest common dominator.
  • Check catchswitch with getFirstNonPHI, instead of getFirstInsertionPt. The latter skips EHPad.

@llvmbot
Copy link
Member

llvmbot commented Jan 16, 2024

@llvm/pr-subscribers-llvm-transforms

Author: XChy (XChy)

Changes

Fixes #78049
This patch has done:

  • Ignore unreachable predecessors when looking for nearest common dominator.
  • Check catchswitch with getFirstNonPHI, instead of getFirstInsertionPt. The latter skips EHPad.

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

3 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/MoveAutoInit.cpp (+6-2)
  • (added) llvm/test/Transforms/MoveAutoInit/catchswitch.ll (+57)
  • (modified) llvm/test/Transforms/MoveAutoInit/loop.ll (+41-2)
diff --git a/llvm/lib/Transforms/Utils/MoveAutoInit.cpp b/llvm/lib/Transforms/Utils/MoveAutoInit.cpp
index a977ad87b79f511..9a5dba219cee506 100644
--- a/llvm/lib/Transforms/Utils/MoveAutoInit.cpp
+++ b/llvm/lib/Transforms/Utils/MoveAutoInit.cpp
@@ -164,6 +164,9 @@ static bool runMoveAutoInit(Function &F, DominatorTree &DT, MemorySSA &MSSA) {
         if (TransitiveSuccessors.count(Pred))
           continue;
 
+        if (!DT.isReachableFromEntry(Pred))
+          continue;
+
         DominatingPredecessor =
             DominatingPredecessor
                 ? DT.findNearestCommonDominator(DominatingPredecessor, Pred)
@@ -178,9 +181,10 @@ static bool runMoveAutoInit(Function &F, DominatorTree &DT, MemorySSA &MSSA) {
 
     // CatchSwitchInst blocks can only have one instruction, so they are not
     // good candidates for insertion.
-    while (isa<CatchSwitchInst>(UsersDominator->getFirstInsertionPt())) {
+    while (isa<CatchSwitchInst>(UsersDominator->getFirstNonPHI())) {
       for (BasicBlock *Pred : predecessors(UsersDominator))
-        UsersDominator = DT.findNearestCommonDominator(UsersDominator, Pred);
+        if (DT.isReachableFromEntry(Pred))
+          UsersDominator = DT.findNearestCommonDominator(UsersDominator, Pred);
     }
 
     // We finally found a place where I can be moved while not introducing extra
diff --git a/llvm/test/Transforms/MoveAutoInit/catchswitch.ll b/llvm/test/Transforms/MoveAutoInit/catchswitch.ll
new file mode 100644
index 000000000000000..25526eb3e7bfe80
--- /dev/null
+++ b/llvm/test/Transforms/MoveAutoInit/catchswitch.ll
@@ -0,0 +1,57 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -S -passes='move-auto-init' -verify-memoryssa | FileCheck %s
+
+declare void @dummy()
+declare void @dummy1()
+
+define void @test() personality ptr @dummy {
+; CHECK-LABEL: define void @test() personality ptr @dummy {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[P:%.*]] = alloca [2 x i16], i32 0, align 2
+; CHECK-NEXT:    br label [[MIDDLE:%.*]]
+; CHECK:       middle:
+; CHECK-NEXT:    store i32 0, ptr [[P]], align 2, !annotation [[META0:![0-9]+]]
+; CHECK-NEXT:    [[CALL:%.*]] = invoke ptr @dummy()
+; CHECK-NEXT:            to label [[CLEAN:%.*]] unwind label [[CATCHBB:%.*]]
+; CHECK:       clean:
+; CHECK-NEXT:    ret void
+; CHECK:       catchbb:
+; CHECK-NEXT:    [[CS:%.*]] = catchswitch within none [label [[PAD:%.*]], label %pad1] unwind to caller
+; CHECK:       pad:
+; CHECK-NEXT:    [[C:%.*]] = catchpad within [[CS]] [i32 0]
+; CHECK-NEXT:    call void @dummy1()
+; CHECK-NEXT:    ret void
+; CHECK:       pad1:
+; CHECK-NEXT:    [[C1:%.*]] = catchpad within [[CS]] [i32 0]
+; CHECK-NEXT:    call void @dummy1()
+; CHECK-NEXT:    ret void
+;
+entry:
+  %p = alloca [2 x i16], i32 0, align 2
+  store i32 0, ptr %p, align 2, !annotation !0
+  br label %middle
+
+middle:
+  %call = invoke ptr @dummy() to label %clean unwind label %catchbb
+
+clean:
+  ret void
+
+catchbb:
+  %cs = catchswitch within none [label %pad, label %pad1] unwind to caller
+
+pad:
+  %c = catchpad within %cs [i32 0]
+  call void @dummy1()
+  ret void
+
+pad1:
+  %c1 = catchpad within %cs [i32 0]
+  call void @dummy1()
+  ret void
+}
+
+!0 = !{!"auto-init"}
+;.
+; CHECK: [[META0]] = !{!"auto-init"}
+;.
diff --git a/llvm/test/Transforms/MoveAutoInit/loop.ll b/llvm/test/Transforms/MoveAutoInit/loop.ll
index 71153e58f4e3523..e0bf6d9401683a2 100644
--- a/llvm/test/Transforms/MoveAutoInit/loop.ll
+++ b/llvm/test/Transforms/MoveAutoInit/loop.ll
@@ -7,7 +7,7 @@ define void @foo(i32 %x) {
 ; CHECK-LABEL: @foo(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[BUFFER:%.*]] = alloca [80 x i32], align 16
-; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 16 [[BUFFER]], i8 -86, i64 320, i1 false), !annotation !0
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 16 [[BUFFER]], i8 -86, i64 320, i1 false), !annotation [[META0:![0-9]+]]
 ; CHECK-NEXT:    br label [[DO_BODY:%.*]]
 ; CHECK:       do.body:
 ; CHECK-NEXT:    [[X_ADDR_0:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[DEC:%.*]], [[DO_COND:%.*]] ]
@@ -53,7 +53,7 @@ define void @bar(i32 %x, i32 %y) {
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[Y:%.*]], 0
 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
 ; CHECK:       if.then:
-; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 16 [[BUFFER]], i8 -86, i64 320, i1 false), !annotation !0
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 16 [[BUFFER]], i8 -86, i64 320, i1 false), !annotation [[META0]]
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], [[Y]]
 ; CHECK-NEXT:    br label [[DO_BODY:%.*]]
 ; CHECK:       do.body:
@@ -99,4 +99,43 @@ if.end:                                           ; preds = %do.end, %entry
   ret void
 }
 
+declare void @dummy()
+
+define void @unreachable_pred() {
+; CHECK-LABEL: @unreachable_pred(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[P:%.*]] = alloca [2 x i16], i32 0, align 2
+; CHECK-NEXT:    store i32 0, ptr [[P]], align 2, !annotation [[META0]]
+; CHECK-NEXT:    br i1 true, label [[LOOP:%.*]], label [[USEBB:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    call void @dummy()
+; CHECK-NEXT:    br label [[LOOP]]
+; CHECK:       a:
+; CHECK-NEXT:    br label [[LOOP]]
+; CHECK:       b:
+; CHECK-NEXT:    br label [[LOOP]]
+; CHECK:       usebb:
+; CHECK-NEXT:    [[USE_P:%.*]] = icmp ult ptr null, [[P]]
+; CHECK-NEXT:    ret void
+;
+entry:
+  %p = alloca [2 x i16], i32 0, align 2
+  store i32 0, ptr %p, align 2, !annotation !0
+  br i1 true, label %loop, label %usebb
+
+loop:
+  call void @dummy()
+  br label %loop
+
+a:
+  br label %loop
+
+b:
+  br label %loop
+
+usebb:
+  %use_p = icmp ult ptr null, %p
+  ret void
+}
+
 !0 = !{!"auto-init"}

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM

@XChy XChy merged commit 26d3cd1 into llvm:main Jan 16, 2024
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…lvm#78232)

Fixes llvm#78049
This patch has done:
- Ignore unreachable predecessors when looking for nearest common
dominator.
- Check catchswitch with `getFirstNonPHI`, instead of
`getFirstInsertionPt`. The latter skips EHPad.
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.

[MoveAutoInit] Assertion `NodeB && "B must be in the tree"' failed.
3 participants