llvm / llvm/llvm-project

IRCE: regression b/w LLVM 18 and 19 due to "Apply loop guards" in loop constrainer

Open
#167,827 3 comments 0 reactions 1 assignee Claimed by @aleks-tmb View on GitHub
loopoptim missed-optimization
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.