Skip to content

[StructurizeCFG] Fix a crash caused by not updating Predicates properly #124051

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

Closed
wants to merge 1 commit into from

Conversation

shiltian
Copy link
Contributor

A very simple IR could crash the pass at assert(BB != Parent);.

define void @foo() {
entry:
  br i1 false, label %cond.true, label %cond.false

cond.true:                                        ; preds = %entry
  br label %cond.end

cond.false:                                       ; preds = %entry
  br label %cond.end

cond.end:                                         ; preds = %cond.false, %cond.true
  ret void
}

TBH I'm not sure if my fix is right. I don't know why we don't update
Predicates after we replace a conditional branch with a branch, given the one
not taken will no longer be a sucessor of the current BB. There are many test
cases need to be updated but I'd like to update them after I fix this properly.
Any help would be appreciated.

…erly

A very simple IR could crash the pass at `assert(BB != Parent);`.

```
define void @foo() {
entry:
  br i1 false, label %cond.true, label %cond.false

cond.true:                                        ; preds = %entry
  br label %cond.end

cond.false:                                       ; preds = %entry
  br label %cond.end

cond.end:                                         ; preds = %cond.false, %cond.true
  ret void
}
```

TBH I'm not sure if my fix is right. I don't know why we don't update
`Predicates` after we replace a conditional branch with a branch, given the one
not taken will no longer be a sucessor of the current BB. There are many test
cases need to be updated but I'd like to update them after I fix this properly.
Any help would be appreciated.
Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@llvmbot
Copy link
Member

llvmbot commented Jan 23, 2025

@llvm/pr-subscribers-backend-amdgpu

Author: Shilei Tian (shiltian)

Changes

A very simple IR could crash the pass at assert(BB != Parent);.

define void @<!-- -->foo() {
entry:
  br i1 false, label %cond.true, label %cond.false

cond.true:                                        ; preds = %entry
  br label %cond.end

cond.false:                                       ; preds = %entry
  br label %cond.end

cond.end:                                         ; preds = %cond.false, %cond.true
  ret void
}

TBH I'm not sure if my fix is right. I don't know why we don't update
Predicates after we replace a conditional branch with a branch, given the one
not taken will no longer be a sucessor of the current BB. There are many test
cases need to be updated but I'd like to update them after I fix this properly.
Any help would be appreciated.


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/Scalar/StructurizeCFG.cpp (+4)
  • (added) llvm/test/Transforms/StructurizeCFG/simple-structurizecfg-crash.ll (+26)
diff --git a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
index b1f742b838f2a1..eaeb6ca4f3e04a 100644
--- a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
@@ -971,6 +971,10 @@ void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
     SubRegion->replaceExit(NewExit);
   } else {
     BasicBlock *BB = Node->getNodeAs<BasicBlock>();
+    for (BasicBlock *Succ : successors(BB)) {
+      if (Succ != NewExit)
+        Predicates[Succ].erase(BB);
+    }
     killTerminator(BB);
     BranchInst *Br = BranchInst::Create(NewExit, BB);
     Br->setDebugLoc(TermDL[BB]);
diff --git a/llvm/test/Transforms/StructurizeCFG/simple-structurizecfg-crash.ll b/llvm/test/Transforms/StructurizeCFG/simple-structurizecfg-crash.ll
new file mode 100644
index 00000000000000..15983c448588b3
--- /dev/null
+++ b/llvm/test/Transforms/StructurizeCFG/simple-structurizecfg-crash.ll
@@ -0,0 +1,26 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=structurizecfg %s -o - | FileCheck %s
+
+define void @foo() {
+; CHECK-LABEL: define void @foo() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[COND_FALSE:.*]]
+; CHECK:       [[COND_TRUE:.*]]:
+; CHECK-NEXT:    br label %[[COND_END:.*]]
+; CHECK:       [[COND_FALSE]]:
+; CHECK-NEXT:    br i1 false, label %[[COND_TRUE]], label %[[COND_END]]
+; CHECK:       [[COND_END]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 false, label %cond.true, label %cond.false
+
+cond.true:                                        ; preds = %entry
+  br label %cond.end
+
+cond.false:                                       ; preds = %entry
+  br label %cond.end
+
+cond.end:                                         ; preds = %cond.false, %cond.true
+  ret void
+}

Comment on lines +974 to +977
for (BasicBlock *Succ : successors(BB)) {
if (Succ != NewExit)
Predicates[Succ].erase(BB);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably should move this into killTerminator where the actual successor removal occurs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

does it mean that we indeed need to update Predicates here? I thought the no-update was on purpose.

Copy link
Contributor

Choose a reason for hiding this comment

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

What makes you think it's on purpose?

The predicates collects branch conditions used in the CFG, so it makes sense to me that you would need to adjust those when the CFG changes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, alright. It has been sitting there for 10+ years so my first reaction is, probably it was designed in that way...

@arsenm arsenm requested a review from jmmartinez January 23, 2025 03:54
@shiltian
Copy link
Contributor Author

shiltian commented Feb 6, 2025

This is not a correct fix and I gave it up.

@shiltian shiltian closed this Feb 6, 2025
@shiltian shiltian deleted the users/shiltian/structurizecfg-crash branch February 6, 2025 03:35
@arsenm
Copy link
Contributor

arsenm commented Feb 6, 2025

This is not a correct fix and I gave it up.

Can you elaborate on how it's not correct? At minimum should commit the xfailed test

@shiltian
Copy link
Contributor Author

shiltian commented Feb 6, 2025

Can you elaborate on how it's not correct?

It looks like the predicate was not constructed correctly at the first place but I don't understand some logic behind how it is constructed after spending several days on it, so I gave it up. After the change made in this PR, a lot of tests need to be updated. I checked some of them. They don't look like the right change.

At minimum should commit the xfailed test

Sure, will do that.

shiltian added a commit that referenced this pull request Feb 6, 2025
I tried to fix it in #124051 but failed to do so. This PR adds the test and
marks it as xfail.
shiltian added a commit that referenced this pull request Feb 10, 2025
I tried to fix it in #124051 but failed to do so. This PR adds the test and
marks it as xfail.
shiltian added a commit that referenced this pull request Feb 10, 2025
…126087)

I tried to fix it in #124051 but failed to do so. This PR adds the test
and
marks it as xfail.
Icohedron pushed a commit to Icohedron/llvm-project that referenced this pull request Feb 11, 2025
…lvm#126087)

I tried to fix it in llvm#124051 but failed to do so. This PR adds the test
and
marks it as xfail.
sivan-shani pushed a commit to sivan-shani/llvm-project that referenced this pull request Feb 24, 2025
…lvm#126087)

I tried to fix it in llvm#124051 but failed to do so. This PR adds the test
and
marks it as xfail.
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