| Issue |
83294
|
| Summary |
[LoopUnroll][RISCV] Crash when unrolling loop containing vector instructions
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
frasercrmck
|
When optimizing for RISC-V _without_ the vector extension enabled, the `RISCVTargetTransformInfo` returns an invalid cost and the loop unroller asserts.
This is happening on both tip (64422cf826354ee1d586c2484ec72d66db898e75) and on LLVM 18.1.0 RC4 (461274b81d8641eab64d494accddc81d7db8a09e).
``` llvm
; RUN: opt -mattr=+f,+d -S --passes=loop-unroll-full -S -disable-output
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-unknown-elf"
define void @foo() {
entry:
br label %for.body
for.body: ; preds = %for.body, %entry
%indvars.iv1 = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
%0 = load float, ptr null, align 4
%splat.splat.i.i.i = shufflevector <2 x float> zeroinitializer, <2 x float> zeroinitializer, <2 x i32> zeroinitializer
%cmp1.i.i.i = fcmp ogt <2 x float> zeroinitializer, zeroinitializer
%splat.splat3.i.i.i = shufflevector <2 x i32> zeroinitializer, <2 x i32> zeroinitializer, <2 x i32> zeroinitializer
%xor3.i.i.i.i.i = select <2 x i1> zeroinitializer, <2 x i32> zeroinitializer, <2 x i32> zeroinitializer
%1 = load float, ptr null, align 4
%splat.splat8.i.i.i = shufflevector <2 x float> zeroinitializer, <2 x float> zeroinitializer, <2 x i32> zeroinitializer
%sub.i.i.i = fsub <2 x float> zeroinitializer, zeroinitializer
%mul.i.i.i = shl i64 0, 0
%2 = load float, ptr null, align 4
%splat.splat.i.i.i.i = shufflevector <2 x float> zeroinitializer, <2 x float> zeroinitializer, <2 x i32> zeroinitializer
%xor3.i.i.i.v.i.i = select <2 x i1> zeroinitializer, <2 x float> zeroinitializer, <2 x float> zeroinitializer
%indvars.iv.next = add i64 %indvars.iv1, 1
%exitcond = icmp ne i64 %indvars.iv1, 8
br i1 %exitcond, label %for.body, label %exit
exit: ; preds = %for.body
ret void
}
```
Should show:
```
opt: /llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp:680: std::optional<EstimatedUnrollCost> analyzeLoopUnrollCost(const llvm::Loop *, unsigned int, llvm::DominatorTree &, llvm::ScalarEvolution &, const SmallPtrSetImpl<const llvm::Value *> &, const llvm::TargetTransformInfo &, unsigned int, unsigned int): Assertion `UnrolledCost.isValid() && RolledDynamicCost.isValid() && "All instructions must have a valid cost, whether the " "loop is rolled or unrolled."' failed.
```
This is a regression against LLVM 17, which reports (with the same input but with `--debug`):
```
Loop Unroll: F[foo] Loop %for.body
Loop Size = Invalid
Not unrolling loop which contains instructions with invalid cost.
```
I've been away from LLVM for a while so don't know if this is a failure in the RISCV cost model or an overly restrictive loop unroller.
It looks like with LLVM 17, the `CodeSize` costs were deemed to be `Invalid` by the `UnrollCostEstimator`, so the unroller exited early. Now since LLVM 18 they are no longer `Invalid` so the unroller tries to calculate profitability in `analyzeLoopUnrollCost` which can't handle `Invalid` costs and asserts.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs