[llvm] 1262871 - [LegalizeTypes] Don't pad cttz_elts_zero_poison with ones when widening op (#206705)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 30 08:16:04 PDT 2026
Author: Luke Lau
Date: 2026-06-30T15:15:59Z
New Revision: 12628715ce61c8db841211eb8683e2f53fa74f0b
URL: https://github.com/llvm/llvm-project/commit/12628715ce61c8db841211eb8683e2f53fa74f0b
DIFF: https://github.com/llvm/llvm-project/commit/12628715ce61c8db841211eb8683e2f53fa74f0b.diff
LOG: [LegalizeTypes] Don't pad cttz_elts_zero_poison with ones when widening op (#206705)
We only need to pad the widened lanes with ones to handle the case for
an all zeroes input. But for cttz_elts_zero_poison, this is already
poison.
The RISC-V scalable vector test can't be precomitted because it crashes
otherwise trying to lower a get_active_lane_mask from
getMaskFromElementCount.
Also while we're here, switch to using TLI.getTypeToTransformTo to be
consistent with other `WidenVecOp_*` implementations.
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
llvm/test/CodeGen/AArch64/intrinsic-cttz-elts-sve.ll
llvm/test/CodeGen/Hexagon/cttz-elts-widen.ll
llvm/test/CodeGen/RISCV/rvv/cttz-elts.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index bdb8cddda4909..547ee11db45e2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -8730,12 +8730,18 @@ SDValue DAGTypeLegalizer::WidenVecOp_VSELECT(SDNode *N) {
SDValue DAGTypeLegalizer::WidenVecOp_CttzElements(SDNode *N) {
SDLoc DL(N);
SDValue Source = N->getOperand(0);
- EVT WideVT = GetWidenedVector(Source).getValueType();
+ EVT WideVT =
+ TLI.getTypeToTransformTo(*DAG.getContext(), Source.getValueType());
- // Pad the widened portion with all-ones so the extra lanes appear as
- // active (non-zero) elements and do not contribute trailing zeros.
- SDValue AllOnes = DAG.getAllOnesConstant(DL, WideVT);
- SDValue WideSource = DAG.getInsertSubvector(DL, AllOnes, Source, 0);
+ SDValue WideSource;
+ if (N->getOpcode() == ISD::CTTZ_ELTS_ZERO_POISON) {
+ WideSource = GetWidenedVector(Source);
+ } else {
+ // Pad the widened portion with all-ones so the extra lanes appear as
+ // active (non-zero) elements and do not contribute trailing zeros.
+ SDValue AllOnes = DAG.getAllOnesConstant(DL, WideVT);
+ WideSource = DAG.getInsertSubvector(DL, AllOnes, Source, 0);
+ }
return DAG.getNode(N->getOpcode(), DL, N->getValueType(0), WideSource,
N->getFlags());
diff --git a/llvm/test/CodeGen/AArch64/intrinsic-cttz-elts-sve.ll b/llvm/test/CodeGen/AArch64/intrinsic-cttz-elts-sve.ll
index fa3673feaee46..4a74a2587b39c 100644
--- a/llvm/test/CodeGen/AArch64/intrinsic-cttz-elts-sve.ll
+++ b/llvm/test/CodeGen/AArch64/intrinsic-cttz-elts-sve.ll
@@ -142,15 +142,8 @@ define i32 @ctz_nxv3i1(<vscale x 3 x i1> %a) {
define i32 @ctz_nxv3i1_poison(<vscale x 3 x i1> %a) {
; CHECK-LABEL: ctz_nxv3i1_poison:
; CHECK: // %bb.0:
-; CHECK-NEXT: rdvl x8, #1
-; CHECK-NEXT: mov w9, #3 // =0x3
-; CHECK-NEXT: ptrue p2.s
-; CHECK-NEXT: lsr x8, x8, #4
-; CHECK-NEXT: mul x8, x8, x9
-; CHECK-NEXT: whilelo p1.s, xzr, x8
-; CHECK-NEXT: not p1.b, p2/z, p1.b
-; CHECK-NEXT: mov p0.b, p1/m, p1.b
-; CHECK-NEXT: brkb p0.b, p2/z, p0.b
+; CHECK-NEXT: ptrue p1.s
+; CHECK-NEXT: brkb p0.b, p1/z, p0.b
; CHECK-NEXT: cntp x0, p0, p0.s
; CHECK-NEXT: ret
%res = call i32 @llvm.experimental.cttz.elts.i32.nxv3i1(<vscale x 3 x i1> %a, i1 1)
diff --git a/llvm/test/CodeGen/Hexagon/cttz-elts-widen.ll b/llvm/test/CodeGen/Hexagon/cttz-elts-widen.ll
index 53ce686d96d5a..4082a75cd16c4 100644
--- a/llvm/test/CodeGen/Hexagon/cttz-elts-widen.ll
+++ b/llvm/test/CodeGen/Hexagon/cttz-elts-widen.ll
@@ -39,8 +39,8 @@ define i32 @cttz_elts_v3i32(<3 x i32> %v) {
; Same shape for the zero-poison variant; padding must still be emitted.
define i32 @cttz_elts_zero_poison_v3i32(<3 x i32> %v) {
; CHECK-LABEL: cttz_elts_zero_poison_v3i32:
-; CHECK: p2 = vcmpw.eq(r1:0,r5:4)
-; CHECK: p0 = vcmpw.eq(r7:6,r5:4)
+; CHECK: p0 = vcmpw.eq(r1:0,r3:2)
+; CHECK: p1 = vcmpw.eq(r7:6,r3:2)
; CHECK: r0 = sub(#4,r0)
%res = call i32 @llvm.experimental.cttz.elts.i32.v3i32(<3 x i32> %v, i1 true)
ret i32 %res
diff --git a/llvm/test/CodeGen/RISCV/rvv/cttz-elts.ll b/llvm/test/CodeGen/RISCV/rvv/cttz-elts.ll
index e761f14b0d4e7..99bf2360a0d44 100644
--- a/llvm/test/CodeGen/RISCV/rvv/cttz-elts.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/cttz-elts.ll
@@ -261,4 +261,40 @@ define i32 @ctz_v3i32(<3 x i32> %a) {
ret i32 %res
}
+define i32 @ctz_v3i32_poison(<3 x i32> %a) {
+; RV32-LABEL: ctz_v3i32_poison:
+; RV32: # %bb.0:
+; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; RV32-NEXT: vmsne.vi v8, v8, 0
+; RV32-NEXT: vfirst.m a0, v8
+; RV32-NEXT: ret
+;
+; RV64-LABEL: ctz_v3i32_poison:
+; RV64: # %bb.0:
+; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; RV64-NEXT: vmsne.vi v8, v8, 0
+; RV64-NEXT: vfirst.m a0, v8
+; RV64-NEXT: ret
+ %res = call i32 @llvm.experimental.cttz.elts(<3 x i32> %a, i1 1)
+ ret i32 %res
+}
+
+define i32 @ctz_nxv3i32_poison(<vscale x 3 x i32> %a) {
+; RV32-LABEL: ctz_nxv3i32_poison:
+; RV32: # %bb.0:
+; RV32-NEXT: vsetvli a0, zero, e32, m2, ta, ma
+; RV32-NEXT: vmsne.vi v10, v8, 0
+; RV32-NEXT: vfirst.m a0, v10
+; RV32-NEXT: ret
+;
+; RV64-LABEL: ctz_nxv3i32_poison:
+; RV64: # %bb.0:
+; RV64-NEXT: vsetvli a0, zero, e32, m2, ta, ma
+; RV64-NEXT: vmsne.vi v10, v8, 0
+; RV64-NEXT: vfirst.m a0, v10
+; RV64-NEXT: ret
+ %res = call i32 @llvm.experimental.cttz.elts(<vscale x 3 x i32> %a, i1 1)
+ ret i32 %res
+}
+
attributes #0 = { vscale_range(2,1024) }
More information about the llvm-commits
mailing list