Issue |
127534
|
Summary |
[SCEV] Assertion `isAvailableAtLoopEntry(RHS, L) && "RHS is not available at Loop Entry"' failed
|
Labels |
llvm:SCEV
|
Assignees |
aleks-tmb
|
Reporter |
aleks-tmb
|
During our local testing, we encountered the assertion failure `isAvailableAtLoopEntry(RHS, L) && "RHS is not available at Loop Entry".
Reduced reproducer:
```llvm
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
target triple = "x86_64-unknown-linux-gnu"
define i64 @"main"(ptr addrspace(1) %p, i1 %check) {
entry:
br label %loop0.pre
loop0.pre:
br i1 %check, label %exit, label %loop0
loop0:
%length = load atomic i32, ptr addrspace(1) %p unordered, align 4
%28 = icmp ugt i32 %length, 1
br i1 %28, label %loop0.out, label %loop1.preheader
loop0.out:
%t = add i32 0, 1
br i1 false, label %loop1.preheader, label %mid
loop1.preheader:
%length.lcssa = phi i32 [ %length, %loop0.out ], [ %length, %loop0 ]
%local = phi i32 [ 0, %loop0 ], [ %t, %loop0.out ]
br label %loop1
loop1:
%iv1 = phi i32 [ 4, %loop1.preheader ], [ %iv1.next, %loop1.guarded ]
%82 = icmp ult i32 %iv1, %length.lcssa
%wc = call i1 @llvm.experimental.widenable.condition()
%guard.chk = and i1 %82, %wc
br i1 %guard.chk, label %loop1.guarded, label %deopt-exit
loop1.guarded:
%iv1.next = add nuw nsw i32 %iv1, 1
%chk = icmp ugt i32 %iv1, 310
br i1 %chk, label %loop1.exit, label %loop1
deopt-exit:
%100 = call i64 (...) @llvm.experimental.deoptimize.i64(i32 13) [ "deopt"() ]
ret i64 %100
loop1.exit:
ret i64 0
mid:
br label %loop0.pre
exit:
ret i64 0
}
declare i64 @foo()
declare i64 @llvm.experimental.deoptimize.i64(...)
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite)
declare noundef i1 @llvm.experimental.widenable.condition()
```
Steps to reproduce:
`$opt -passes='print<scalar-evolution>,loop-mssa(licm,loop-simplifycfg,loop-predication)'`
Proof: https://godbolt.org/z/8hsbahTjq
Looks like `LoopSimplifyCFGPass` is guilty - it doesn’t invalidate SCEV when removing a dead exit:
```c++
void handleDeadExits() {
...
for (Instruction *I : DeadInstructions) {
SE.forgetBlockAndLoopDispositions(I);
I->replaceAllUsesWith(PoisonValue::get(I->getType()));
I->eraseFromParent();
}
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs