| Issue |
181273
|
| Summary |
[SCCP] Crash on optimized codegen due to undefined if condition
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
namikukr-qc
|
Hi,
When compiling code with optimization level higher than -O0, there's a crash in the following simple test:
```
#include <stdio.h>
int main() {
puts("starting");
goto test;
int a = 1;
test: if (a == 1) {
puts("undefined behavior");
}
puts("unreachable on any optimization level");
return 0;
}
```
The condition in the if is undefined. Here is llvm IR for main, before IPSCCP:
```
define dso_local i32 @main() #0 {
entry:
%call = call i32 @puts(ptr noundef @.str)
br i1 undef, label %if.then, label %if.end
if.then: ; preds = %entry
%call1 = call i32 @puts(ptr noundef @.str.1)
br label %if.end
if.end: ; preds = %if.then, %entry
%call2 = call i32 @puts(ptr noundef @.str.2)
ret i32 0
}
```
After IPSCCP:
```
define dso_local i32 @main() #0 {
entry:
%call = call i32 @puts(ptr noundef @.str)
unreachable
}
```
It seems like anything after the if gets eaten away. I looked through `llvm/lib/Transforms/IPO/SCCP.cpp` and `llvm/lib/Transforms/Utils/SCCPSolver.cpp`, and the culprit seems to be the function `SCCPInstVisitor::getFeasibleSuccessors`, where it is determined that an if statement with an unknown condition has no successors. This domino-effects into any code in the same function succeeding the if not existing.
Specifically, line 1265 in `SCCPSolver.cpp`:
```
if (!BCValue.isUnknownOrUndef())
Succs[0] = Succs[1] = true;
return;
```
All feasible successors are marked executable in `SCCPInstVisitor::visitTerminator`:
```
// Mark all feasible successors executable.
for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
if (SuccFeasible[i])
markEdgeExecutable(BB, TI.getSuccessor(i));
```
If the condition is undefined, both successors are not marked executable, in which case this happens in `SCCP.cpp`:
```
for (BasicBlock &BB : F) {
if (!Solver.isBlockExecutable(&BB)) {
LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << BB);
++NumDeadBlocks;
MadeChanges = true;
if (&BB != &F.front())
BlocksToErase.push_back(&BB);
continue;
}
...
```
Since each succeeding block after the if is a successor of `if.end`, the entire remainder of the function vanishes.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs