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

Reply via email to