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

Reply via email to