<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/83294>83294</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[LoopUnroll][RISCV] Crash when unrolling loop containing vector instructions
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
frasercrmck
</td>
</tr>
</table>
<pre>
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.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMV1uP27gO_jXKC5HAlq95yEMmaYABeopFpzvncSFbdKxTWTIkOTOZX38g2bm20-3uYoHOxYklivz4iZRIZq3YK8QVyR5Itp2xwbXarBrDLJradPXXWaX5cfXfFhXo3olOvAm1h0Yb-Pz4tJk_wx8vwrV6cH-AaxEOWDttAF8dKiu0AlSsksgJ3YR5kkd-3fMXZvbovhimbKNN96gaTfIIDLrBKAtMgVAHJgWHWlsHTPGwXGrdw6CMlhINMGvROLsg0ZZE6_H5pRUWhIWW9T0qj1UrqLRrwYkeCC3zNKW0bkqaJ1mKGPOszGualinWBeV5zqtyWWKREboMZrWCjx-f_wNxuYgXEXzepF5Lmse0SKsy5mWexsiqPOXpMmV1zXldxrzgVcmiJRK6vIFH8mj8AykP3TSWPMDn3z-RZO0phnnHnDMk2RL60BC6IfSBw_wJ5vPeO2xJsvU0zEca5s0gZZjmwnqq53pw_eBG1S7QDJw5JtlRDw5IsgVCKc47kqxx3pNknafhMRfnLzEtSbKOaTlXCR3HnvwYpTdqnRG9xJNKI2x9yNP5oL4q_aLOnyib88LxybERCuGgBQeSRo3WxCtfAikeRglUzhxJMskDVAYkq1ACoVmjzcIH5bXG81iyhp_98bT3BrmdHLgophv_OmKYABCaCcUPzNiFOMRhRd8KEHkKJHu4nV4ofHWTkpNOINk2DGUPEF0bCBMXI1FQLTXj0EjNgpreGVCDlP47k2KvIJ1WEJrZXjK3GJ_C_wYFth2aRuKUjSTZUHidFCYf4A2NFko4waR4QxPg_LSI8BHxrcDFhbrr4ysoTd31oPfuZ0y8r_TKzeTP_HwH4Z-68Bd8fNVmgnGBghLrs5ci_rchxH8pUu44LH-BWPGIhuo6UuxQ_f0oITTrBnnjlwz5GdItuuKB_uMc-wWy7CoCD38zBv8J0u8di-HcCzgY5-PReHNqer3xhVV8Fa7WiocVwp8SCt9ZVV7dAyK-Xuxnv70Zrge95PVVEd6T9Q-O_8mWQReuqGlxsb27wa-VPrV6kBxsq1_Ot9Z3xXU_Gqe7cP_TnRQVobtzIWQJ3T3VTDJD6O6j1v3v4Zb_jVm7qPtwW5eR12Ad95YSr1FoxSRJNh-sEx1zyMdFG23D3jHF5PENL9rCBC1rrawb65CgyQsAoWtP36BCYchBqJAfF6mt7oRiTpsvBhEIzW-nR_AfDloOHtdJYLT11DEpf3PmCd1j13vI9xiemRwwgEg-3K69yHyndjyJ3sO-fV964tahaAzQ8mjkA7lnZCHss684T7WI15jD5zC_PSrWifp9MULpWkoQyjoz1F69hW6wDlp2QGBwqWU9rJcWXYtmrIgp9f-hshUWRjygzanM5QtfPdECGibC2_tReKp9GRjcG7ShAGd75lFNRWwxmhd1CwZ7bZz11awv4QMYyzoEofrBQTU4COMkj-ZzjtWw9-YCiT8I8BBEI62e7R3JHnx9l21hCq9v8iyMP4m3sZB8HMv-0-Qn7SYifCkfSBrR11o579gt5QHwdefwI7oeCS0OCBWiAvbCjtAY3Y08-f6GeUsSwWrgWhFaOPAFLYgG3JlovymD8ZwF_kJvM7YsneYo_T4yBfqARh7BoHVG1E4c7jqZmxbh0fnJrxak-IqjR1d7NzVRG83Rc-Y7CW_OwgsaBI7YIQenoQpiJzbzCKrjae3lEJgODG3Czm68q17m3GD5sxI5IDPyuIBP-gWsUDWeGiIvfARmEJQGqdUezZ3Re4XOCLQeXs1kPUjmEHqjG-FYJaRwR88jyaPvn1h5dNp7Nm5HyxSX936ObPjO7dQezvgq4ctkyWa4iotoGSfLYpnN2lVVLilbFk2x5DXLIqx4VRclW9YswyjN85lY0YimEaVlXERJlC0qXmJV1UlURLSoMSJphB0TcuFPp4U2-5mwdsBVmdBlOgt3kA29NaUKXyBM-nTOtjOz8mvm1bC3JI2ksM5etDjhZGjKLxT4PiF7CAHms2ljmG39QaLu82PKDP8-VSbXKTIbjFy1zvXW5zHdEbrbC9cO1aLW3dW15LH1Rv8Pa0foLgD3d1Nw7P8BAAD__5ftEHA">