IRCE: regression b/w LLVM 18 and 19 due to "Apply loop guards" in loop constrainer
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
https://godbolt.org/z/hd46Eq1xb
Test: `opt -passes=irce` on
```
define i32 @test(i32 %x) {
bb:
%add = add nuw i32 %x, 16
%icmp = icmp slt i32 %add, %x
br i1 %icmp, label %bb2, label %bb1
bb1: ; preds = %bb4, %bb
ret i32 0
bb2: ; preds = %bb4, %bb
%phi = phi i32 [ %add5, %bb4 ], [ %add, %bb ]
%icmp3 = icmp ult i32 %phi, 1
br i1 %icmp3, label %bb4, label %bb7
bb4: ; preds = %bb2
%add5 = add i32 %phi, 1
%icmp6 = icmp slt i32 %add5, %x
br i1 %icmp6, label %bb2, label %bb1
bb7: ; preds = %bb2
ret i32 0
}
```
IRCE is not able to handle range check from this case starting version 19. The reason of this lies here:
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Utils/LoopConstrainer.cpp#L91
```
auto StartLG = SE.applyLoopGuards(Start, L);
auto BoundLG = SE.applyLoopGuards(BoundSCEV, L);
```
This makes the predicates unprovable in some cases. Remove this code (just take `StartLG = Start` and `BoundLG = BOundSCEV`)and it will become provable.
There are also cases when these loop guards to help, off course. But this change is at least controversial.
The workaround I can propose is to factor out this code and try to prove with and without loop guards. Alternatively, investigate why SCEV cannot prove it.
Contributor guide
Assessment
This issue has not been assessed yet.