[llvm] [RISCV] Fix crash costing cttz.elts without fixed-length RVV. (PR #226181)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 07:25:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Florian Hahn (fhahn)
<details>
<summary>Changes</summary>
With +zve32x fixed-length vectors are not legalized to RVV types and getTypeLegalizationCost returns a scalar MVT. Skip non-vector types and return Invalid instead of asserting in the getVectorElementType call below.
We may be able to give more accurate costs, but I am not familiar enough with the details.
Hit this while fuzzing some LoopVectorize changes.
Aided by Claude Opus.
---
Full diff: https://github.com/llvm/llvm-project/pull/226181.diff
2 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp (+2)
- (modified) llvm/test/Analysis/CostModel/RISCV/cttz_elts.ll (+37-18)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index 7f65e3dd4456a..bd87a7cd905e2 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -1783,6 +1783,8 @@ RISCVTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
InstructionCost Cost = 0;
Type *ArgTy = ICA.getArgTypes()[0];
auto LT = getTypeLegalizationCost(ArgTy);
+ if (!LT.second.isVector())
+ break;
// If the element type is not i1, do a comparison with all-zeros.
if (LT.second.getVectorElementType() != MVT::i1)
diff --git a/llvm/test/Analysis/CostModel/RISCV/cttz_elts.ll b/llvm/test/Analysis/CostModel/RISCV/cttz_elts.ll
index 07cf67881289d..35c6085abfe57 100644
--- a/llvm/test/Analysis/CostModel/RISCV/cttz_elts.ll
+++ b/llvm/test/Analysis/CostModel/RISCV/cttz_elts.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
-; RUN: opt < %s -passes="print<cost-model>" 2>&1 -disable-output -mtriple=riscv64 -mattr=+v | FileCheck %s
+; RUN: opt < %s -passes="print<cost-model>" 2>&1 -disable-output -mtriple=riscv64 -mattr=+v | FileCheck %s --check-prefixes=CHECK,V
+; RUN: opt < %s -passes="print<cost-model>" 2>&1 -disable-output -mtriple=riscv64 -mattr=+zve32x | FileCheck %s --check-prefixes=CHECK,ZVE32X
define void @foo_no_vscale_range() {
; CHECK-LABEL: 'foo_no_vscale_range'
@@ -134,23 +135,41 @@ define void @foo_vscale_range_2_16() vscale_range(2,16) {
define void @foo_fixed_len_vectors() {
-; CHECK-LABEL: 'foo_fixed_len_vectors'
-; CHECK-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v2i1.false = call i32 @llvm.experimental.cttz.elts.i32.v2i1(<2 x i1> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v4i1.false = call i32 @llvm.experimental.cttz.elts.i32.v4i1(<4 x i1> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v8i1.false = call i32 @llvm.experimental.cttz.elts.i32.v8i1(<8 x i1> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v64i1.false = call i32 @llvm.experimental.cttz.elts.i32.v64i1(<64 x i1> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v128i1.false = call i32 @llvm.experimental.cttz.elts.i32.v128i1(<128 x i1> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 24 for instruction: %res.i32.v1024i1.false = call i32 @llvm.experimental.cttz.elts.i32.v1024i1(<1024 x i1> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 48 for instruction: %res.i32.v2048i1.false = call i32 @llvm.experimental.cttz.elts.i32.v2048i1(<2048 x i1> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %res.i32.v2i1.true = call i32 @llvm.experimental.cttz.elts.i32.v2i1(<2 x i1> poison, i1 true)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 16 for instruction: %res.i32.v2048i1.true = call i32 @llvm.experimental.cttz.elts.i32.v2048i1(<2048 x i1> poison, i1 true)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %res.i32.v2i32 = call i32 @llvm.experimental.cttz.elts.i32.v2i32(<2 x i32> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %res.i32.v4i32 = call i32 @llvm.experimental.cttz.elts.i32.v4i32(<4 x i32> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 11 for instruction: %res.i32.v32i32 = call i32 @llvm.experimental.cttz.elts.i32.v32i32(<32 x i32> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %res.i32.v2i33 = call i32 @llvm.experimental.cttz.elts.i32.v2i33(<2 x i33> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %res.i32.v4i33 = call i32 @llvm.experimental.cttz.elts.i32.v4i33(<4 x i33> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 22 for instruction: %res.i32.v32i33 = call i32 @llvm.experimental.cttz.elts.i32.v32i33(<32 x i33> poison, i1 false)
-; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
+; V-LABEL: 'foo_fixed_len_vectors'
+; V-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v2i1.false = call i32 @llvm.experimental.cttz.elts.i32.v2i1(<2 x i1> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v4i1.false = call i32 @llvm.experimental.cttz.elts.i32.v4i1(<4 x i1> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v8i1.false = call i32 @llvm.experimental.cttz.elts.i32.v8i1(<8 x i1> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v64i1.false = call i32 @llvm.experimental.cttz.elts.i32.v64i1(<64 x i1> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 3 for instruction: %res.i32.v128i1.false = call i32 @llvm.experimental.cttz.elts.i32.v128i1(<128 x i1> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 24 for instruction: %res.i32.v1024i1.false = call i32 @llvm.experimental.cttz.elts.i32.v1024i1(<1024 x i1> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 48 for instruction: %res.i32.v2048i1.false = call i32 @llvm.experimental.cttz.elts.i32.v2048i1(<2048 x i1> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %res.i32.v2i1.true = call i32 @llvm.experimental.cttz.elts.i32.v2i1(<2 x i1> poison, i1 true)
+; V-NEXT: Cost Model: Found an estimated cost of 16 for instruction: %res.i32.v2048i1.true = call i32 @llvm.experimental.cttz.elts.i32.v2048i1(<2048 x i1> poison, i1 true)
+; V-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %res.i32.v2i32 = call i32 @llvm.experimental.cttz.elts.i32.v2i32(<2 x i32> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %res.i32.v4i32 = call i32 @llvm.experimental.cttz.elts.i32.v4i32(<4 x i32> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 11 for instruction: %res.i32.v32i32 = call i32 @llvm.experimental.cttz.elts.i32.v32i32(<32 x i32> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %res.i32.v2i33 = call i32 @llvm.experimental.cttz.elts.i32.v2i33(<2 x i33> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %res.i32.v4i33 = call i32 @llvm.experimental.cttz.elts.i32.v4i33(<4 x i33> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 22 for instruction: %res.i32.v32i33 = call i32 @llvm.experimental.cttz.elts.i32.v32i33(<32 x i33> poison, i1 false)
+; V-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
+;
+; ZVE32X-LABEL: 'foo_fixed_len_vectors'
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v2i1.false = call i32 @llvm.experimental.cttz.elts.i32.v2i1(<2 x i1> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v4i1.false = call i32 @llvm.experimental.cttz.elts.i32.v4i1(<4 x i1> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v8i1.false = call i32 @llvm.experimental.cttz.elts.i32.v8i1(<8 x i1> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v64i1.false = call i32 @llvm.experimental.cttz.elts.i32.v64i1(<64 x i1> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v128i1.false = call i32 @llvm.experimental.cttz.elts.i32.v128i1(<128 x i1> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v1024i1.false = call i32 @llvm.experimental.cttz.elts.i32.v1024i1(<1024 x i1> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v2048i1.false = call i32 @llvm.experimental.cttz.elts.i32.v2048i1(<2048 x i1> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v2i1.true = call i32 @llvm.experimental.cttz.elts.i32.v2i1(<2 x i1> poison, i1 true)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v2048i1.true = call i32 @llvm.experimental.cttz.elts.i32.v2048i1(<2048 x i1> poison, i1 true)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v2i32 = call i32 @llvm.experimental.cttz.elts.i32.v2i32(<2 x i32> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v4i32 = call i32 @llvm.experimental.cttz.elts.i32.v4i32(<4 x i32> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v32i32 = call i32 @llvm.experimental.cttz.elts.i32.v32i32(<32 x i32> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v2i33 = call i32 @llvm.experimental.cttz.elts.i32.v2i33(<2 x i33> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v4i33 = call i32 @llvm.experimental.cttz.elts.i32.v4i33(<4 x i33> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Invalid cost for instruction: %res.i32.v32i33 = call i32 @llvm.experimental.cttz.elts.i32.v32i33(<32 x i33> poison, i1 false)
+; ZVE32X-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
;
%res.i32.v2i1.false = call i32 @llvm.experimental.cttz.elts.i32.v2i1(<2 x i1> poison, i1 false)
%res.i32.v4i1.false = call i32 @llvm.experimental.cttz.elts.i32.v4i1(<4 x i1> poison, i1 false)
``````````
</details>
https://github.com/llvm/llvm-project/pull/226181
More information about the llvm-commits
mailing list