llvm / llvm/llvm-project

[SCEV] Segmentation fault in ScalarEvolution during 'Induction Variable Users' pass

Open
#206,633 0 comments 0 reactions 0 assignees View on GitHub
crash llvm:SCEV
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Clang crashes when compiling a nested loop structure that combines a large out-of-bounds loop step expression with `[[assume]]` attributes. The crash occurs inside the `Induction Variable Users` pass during ScalarEvolution analysis.

This test case was generated by fuzzer and reduced by Creduce.

Tested on: `clang version 23.0.0git (https://github.com/llvm/llvm-project.git 195ca1f266d88b5f49fbb5a4612214a20b48886b)`
- Target: x86_64-unknown-linux-gnu
- Optimization Level: -O3

Reproducer: https://godbolt.org/z/h8jzrcn7c
Note: The compilation takes about 1 minute before crashing, which triggers a timeout on Compiler Explorer.

Attachments:
- [crash-bddae1.sh](https://github.com/user-attachments/files/29487694/crash-bddae1.sh)
- [crash-bddae1.cpp](https://github.com/user-attachments/files/29487708/crash-bddae1.cpp)
- [backtrace.txt](https://github.com/user-attachments/files/29487709/backtrace.txt)

Reproduce locally:
```cpp
// crash.cpp
short d[3][3][3];
#include
void a(int l, short b, char c, short e, short f, short g) {
#pragma clang loop unroll(enable)
for (int h; h < 23LL; h += 1LL)
for (short i = 0; i < 4 + 22; i += -3224943361791975759LL - 40623) {
[[assume(e - 17695 == 23)]];
[[assume((f ? c >= l : b) - 20846 == 4)]];
for (short j = 0; j < e - 17695; j += b - 20846)
for (short k(std::min((int)g, 0) + 9); k < 0; k += 3)
d[k][h][h] = 0;
}
}
```

```sh
clang crash.cpp -O3
```

Backtrace:
```
1. parser at end of file
2. Code generation
3. Running pass 'Function Pass Manager' on module 'crash.cpp'.
4. Running pass 'Loop Pass Manager' on function '@_Z1aiscsss'
5. Running pass 'Induction Variable Users' on basic block '%for.body28.us.us.us.12.22.5'
...
#5 0x00005ffd8cb28047 llvm::ScalarEvolution::getAddExpr(llvm::SmallVectorImpl>&, llvm::SCEVNoWrapFlags, unsigned int) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x349b047)
#6 0x00005ffd8cb29d0b llvm::ScalarEvolution::getAddExpr(llvm::SmallVectorImpl>&, llvm::SCEVNoWrapFlags, unsigned int) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x349cd0b)
#7 0x00005ffd8b799eaa llvm::ScalarEvolution::getAddExpr(llvm::SCEVUseT, llvm::SCEVUseT, llvm::SCEVNoWrapFlags, unsigned int) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x210ceaa)
#8 0x00005ffd8cb2f625 llvm::ScalarEvolution::isKnownPredicateViaConstantRanges(llvm::CmpPredicate, llvm::SCEVUseT, llvm::SCEVUseT) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x34a2625)
...
#21 0x00005ffd8cb15676 llvm::ScalarEvolution::isKnownPredicateViaConstantRanges(llvm::CmpPredicate, llvm::SCEVUseT, llvm::SCEVUseT)::'lambda'(bool)::operator()(bool) const ScalarEvolution.cpp:0:0
#22 0x00005ffd8cb2f5d7 llvm::ScalarEvolution::isKnownPredicateViaConstantRanges(llvm::CmpPredicate, llvm::SCEVUseT, llvm::SCEVUseT) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x34a25d7)
#23 0x00005ffd8cb2f727 llvm::ScalarEvolution::isKnownViaNonRecursiveReasoning(llvm::CmpPredicate, llvm::SCEVUseT, llvm::SCEVUseT) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x34a2727)
...
#230 0x00005ffd8cb15676 llvm::ScalarEvolution::isKnownPredicateViaConstantRanges(llvm::CmpPredicate, llvm::SCEVUseT, llvm::SCEVUseT)::'lambda'(bool)::operator()(bool) const ScalarEvolution.cpp:0:0
#231 0x00005ffd8cb2f5d7 llvm::ScalarEvolution::isKnownPredicateViaConstantRanges(llvm::CmpPredicate, llvm::SCEVUseT, llvm::SCEVUseT) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x34a25d7)
#232 0x00005ffd8cb2f727 llvm::ScalarEvolution::isKnownViaNonRecursiveReasoning(llvm::CmpPredicate, llvm::SCEVUseT, llvm::SCEVUseT) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x34a2727)
...
#255 0x00005ffd8cb4528a llvm::ScalarEvolution::isImpliedCond(llvm::CmpPredicate, llvm::SCEV const*, llvm::SCEV const*, llvm::Value const*, bool, llvm::Instruction const*) (/data/lenovo/compiler-build/llvm/llvm-project/build/bin/clang-23+0x34b828a)
clang: error: unable to execute command: Segmentation fault (core dumped)
clang: error: clang frontend command failed with exit code -2 (use -v to see invocation)
clang version 23.0.0git (https://github.com/llvm/llvm-project.git 195ca1f266d88b5f49fbb5a4612214a20b48886b)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /data/lenovo/compiler-build/llvm/llvm-project/build/bin
Build config: +assertions
clang: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:
clang: note: diagnostic msg: /tmp/crash-bddae1.cpp
clang: note: diagnostic msg: /tmp/crash-bddae1.sh
clang: note: diagnostic msg:

********************
Aborted (core dumped)
```

Contributor guide

Open the contributing guide

Research direction

Start by compiling the attached crash-bddae1.cpp with `clang crash.cpp -O3` and compare the failure with backtrace.txt. Read the ScalarEvolution.cpp frames around the Induction Variable Users pass and determine why this reproducer reaches the recursive analysis path. Done means the supplied command no longer segfaults on the reproducer and the fix has regression coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.