[llvm] [RISCV] Fix ReplaceNodeResults of Intrinsic::experimental_cttz_elts for RV32 (PR #174992)

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 8 08:22:38 PST 2026


https://github.com/asb updated https://github.com/llvm/llvm-project/pull/174992

>From 5d8f5eea70256547676bfddefcbb4c29dc4f6141 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 8 Jan 2026 15:13:41 +0000
Subject: [PATCH 1/2] [RISCV] Fix ReplaceNodeResults of
 Intrinsic::experimental_cttz_elts for RV32

The test case added in this patch crashes on rv32v without this fix. We
attempt to trunc the i32 type of the select produced by lowerCttzElts to
i64, which asserts. Use getZExtOrTrunc instead.
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  3 +-
 .../RISCV/intrinsic-cttz-elts-vscale.ll       | 33 ++++++++++++++-----
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index f87c45a77dc64..c9c52e842999a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -15416,8 +15416,7 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
     }
     case Intrinsic::experimental_cttz_elts: {
       SDValue Res = lowerCttzElts(N, DAG, Subtarget);
-      Results.push_back(
-          DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), Res));
+      Results.push_back(DAG.getZExtOrTrunc(Res, DL, N->getValueType(0)));
       return;
     }
     case Intrinsic::riscv_orc_b:
diff --git a/llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll b/llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll
index e0aed2d4f90ff..73aad257ac336 100644
--- a/llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll
+++ b/llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll
@@ -154,6 +154,23 @@ define i32 @ctz_nxv16i1(<vscale x 16 x i1> %pg, <vscale x 16 x i1> %a) {
   ret i32 %res
 }
 
+define i64 @i64_ctz_nxv16i1(<vscale x 16 x i1> %pg, <vscale x 16 x i1> %a) {
+; RV32-LABEL: i64_ctz_nxv16i1:
+; RV32:       # %bb.0:
+; RV32-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
+; RV32-NEXT:    vfirst.m a0, v8
+; RV32-NEXT:    li a1, 0
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: i64_ctz_nxv16i1:
+; RV64:       # %bb.0:
+; RV64-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
+; RV64-NEXT:    vfirst.m a0, v8
+; RV64-NEXT:    ret
+  %res = call i64 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> %a, i1 1)
+  ret i64 %res
+}
+
 define i32 @ctz_nxv16i1_poison(<vscale x 16 x i1> %pg, <vscale x 16 x i1> %a) {
 ; RV32-LABEL: ctz_nxv16i1_poison:
 ; RV32:       # %bb.0:
@@ -175,20 +192,20 @@ define i32 @ctz_v16i1(<16 x i1> %pg, <16 x i1> %a) {
 ; RV32:       # %bb.0:
 ; RV32-NEXT:    vsetivli zero, 16, e8, m1, ta, ma
 ; RV32-NEXT:    vfirst.m a0, v8
-; RV32-NEXT:    bgez a0, .LBB4_2
+; RV32-NEXT:    bgez a0, .LBB5_2
 ; RV32-NEXT:  # %bb.1:
 ; RV32-NEXT:    li a0, 16
-; RV32-NEXT:  .LBB4_2:
+; RV32-NEXT:  .LBB5_2:
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: ctz_v16i1:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    vsetivli zero, 16, e8, m1, ta, ma
 ; RV64-NEXT:    vfirst.m a0, v8
-; RV64-NEXT:    bgez a0, .LBB4_2
+; RV64-NEXT:    bgez a0, .LBB5_2
 ; RV64-NEXT:  # %bb.1:
 ; RV64-NEXT:    li a0, 16
-; RV64-NEXT:  .LBB4_2:
+; RV64-NEXT:  .LBB5_2:
 ; RV64-NEXT:    ret
   %res = call i32 @llvm.experimental.cttz.elts.i32.v16i1(<16 x i1> %a, i1 0)
   ret i32 %res
@@ -215,20 +232,20 @@ define i16 @ctz_v8i1_i16_ret(<8 x i1> %a) {
 ; RV32:       # %bb.0:
 ; RV32-NEXT:    vsetivli zero, 8, e8, mf2, ta, ma
 ; RV32-NEXT:    vfirst.m a0, v0
-; RV32-NEXT:    bgez a0, .LBB6_2
+; RV32-NEXT:    bgez a0, .LBB7_2
 ; RV32-NEXT:  # %bb.1:
 ; RV32-NEXT:    li a0, 8
-; RV32-NEXT:  .LBB6_2:
+; RV32-NEXT:  .LBB7_2:
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: ctz_v8i1_i16_ret:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    vsetivli zero, 8, e8, mf2, ta, ma
 ; RV64-NEXT:    vfirst.m a0, v0
-; RV64-NEXT:    bgez a0, .LBB6_2
+; RV64-NEXT:    bgez a0, .LBB7_2
 ; RV64-NEXT:  # %bb.1:
 ; RV64-NEXT:    li a0, 8
-; RV64-NEXT:  .LBB6_2:
+; RV64-NEXT:  .LBB7_2:
 ; RV64-NEXT:    ret
   %res = call i16 @llvm.experimental.cttz.elts.i16.v8i1(<8 x i1> %a, i1 0)
   ret i16 %res

>From e96a7a5ced6c44e220f185d040206d2ebd7badd2 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 8 Jan 2026 16:22:21 +0000
Subject: [PATCH 2/2] Fix mismatched type in intrinsic name

---
 llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll b/llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll
index 73aad257ac336..28ab573f59ac0 100644
--- a/llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll
+++ b/llvm/test/CodeGen/RISCV/intrinsic-cttz-elts-vscale.ll
@@ -167,7 +167,7 @@ define i64 @i64_ctz_nxv16i1(<vscale x 16 x i1> %pg, <vscale x 16 x i1> %a) {
 ; RV64-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
 ; RV64-NEXT:    vfirst.m a0, v8
 ; RV64-NEXT:    ret
-  %res = call i64 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> %a, i1 1)
+  %res = call i64 @llvm.experimental.cttz.elts.i64.nxv16i1(<vscale x 16 x i1> %a, i1 1)
   ret i64 %res
 }
 



More information about the llvm-commits mailing list