Description
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 (64422cf) and on LLVM 18.1.0 RC4 (461274b).
; 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.
Metadata
Metadata
Assignees
Type
Projects
Status