[llvm] [LLVM][SelectionDAG] Reduce chances of a split VSETCC being rewidened. (PR #191438)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 10 07:54:27 PDT 2026
https://github.com/paulwalker-arm created https://github.com/llvm/llvm-project/pull/191438
This is a reimplementation of https://github.com/llvm/llvm-project/pull/139295 but without introducing a potential infinite type legalisation loop whereby splitting a SETCC requires the result to be rewidened.
Fixes https://github.com/llvm/llvm-project/issues/190773
>From dd5b23d73d469aa933ee3ee5c24162d407884068 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Fri, 10 Apr 2026 14:13:43 +0100
Subject: [PATCH] [LLVM][SelectionDAG] Reduce chances of a split VSETCC being
rewidened.
This is a reimplementation of https://github.com/llvm/llvm-project/pull/139295
but without introducing a potential infinite type legalisation loop
whereby splitting a SETCC requires the result to be rewidened.
Fixes https://github.com/llvm/llvm-project/issues/190773
---
.../SelectionDAG/LegalizeVectorTypes.cpp | 20 +++++--
.../test/CodeGen/WebAssembly/simd-pr190773.ll | 52 +++++++++++++++++++
2 files changed, 69 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/CodeGen/WebAssembly/simd-pr190773.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index a96c77bc6a4e9..b1190abdb34f2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -4796,9 +4796,15 @@ SDValue DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode *N) {
GetSplitVector(N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
GetSplitVector(N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
+ LLVMContext &Context = *DAG.getContext();
EVT VT = N->getValueType(0);
- EVT PartResVT = Lo0.getValueType().changeElementType(*DAG.getContext(),
- VT.getScalarType());
+ EVT PartResVT =
+ Lo0.getValueType().changeElementType(Context, VT.getScalarType());
+
+ // If splitting the operand is going to cause the result to be widened, we're
+ // better of using an i1 vector that can be promoted instead.
+ if (getTypeAction(PartResVT) == TargetLowering::TypeWidenVector)
+ PartResVT = PartResVT.changeElementType(Context, MVT::i1);
if (Opc == ISD::SETCC) {
LoRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Lo0, Lo1, N->getOperand(2));
@@ -4823,7 +4829,15 @@ SDValue DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode *N) {
N->getOperand(2), MaskHi, EVLHi);
}
- return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, LoRes, HiRes);
+ EVT ConcatVT = PartResVT.getDoubleNumVectorElementsVT(Context);
+ SDValue Con = DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT, LoRes, HiRes);
+ if (ConcatVT == VT)
+ return Con;
+
+ EVT OpVT = N->getOperand(0).getValueType();
+ ISD::NodeType ExtendCode =
+ TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
+ return DAG.getNode(ExtendCode, DL, VT, Con);
}
diff --git a/llvm/test/CodeGen/WebAssembly/simd-pr190773.ll b/llvm/test/CodeGen/WebAssembly/simd-pr190773.ll
new file mode 100644
index 0000000000000..4c7fa2d92726c
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/simd-pr190773.ll
@@ -0,0 +1,52 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=wasm32 -mattr=+simd128 | FileCheck %s
+
+define <4 x i1> @f(ptr %out, <4 x half> %v) {
+; CHECK-LABEL: f:
+; CHECK: .functype f (i32, i32, i32, i32, i32) -> (v128)
+; CHECK-NEXT: .local f32, f32, f32
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 4
+; CHECK-NEXT: call __extendhfsf2
+; CHECK-NEXT: local.set 5
+; CHECK-NEXT: local.get 3
+; CHECK-NEXT: call __extendhfsf2
+; CHECK-NEXT: local.set 6
+; CHECK-NEXT: local.get 2
+; CHECK-NEXT: call __extendhfsf2
+; CHECK-NEXT: local.set 7
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: call __extendhfsf2
+; CHECK-NEXT: f32.const 0x0p0
+; CHECK-NEXT: f32.ne
+; CHECK-NEXT: i32.sub
+; CHECK-NEXT: i16x8.splat
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 7
+; CHECK-NEXT: f32.const 0x0p0
+; CHECK-NEXT: f32.ne
+; CHECK-NEXT: i32.sub
+; CHECK-NEXT: i16x8.replace_lane 1
+; CHECK-NEXT: i32x4.extend_low_i16x8_s
+; CHECK-NEXT: i64x2.extend_low_i32x4_s
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 6
+; CHECK-NEXT: f32.const 0x0p0
+; CHECK-NEXT: f32.ne
+; CHECK-NEXT: i32.sub
+; CHECK-NEXT: i16x8.splat
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 5
+; CHECK-NEXT: f32.const 0x0p0
+; CHECK-NEXT: f32.ne
+; CHECK-NEXT: i32.sub
+; CHECK-NEXT: i16x8.replace_lane 1
+; CHECK-NEXT: i32x4.extend_low_i16x8_s
+; CHECK-NEXT: i64x2.extend_low_i32x4_s
+; CHECK-NEXT: i8x16.shuffle 0, 1, 8, 9, 16, 17, 24, 25, 0, 1, 0, 1, 0, 1, 0, 1
+; CHECK-NEXT: i32x4.extend_low_i16x8_u
+; CHECK-NEXT: # fallthrough-return
+ %cmp = fcmp une <4 x half> %v, zeroinitializer
+ ret <4 x i1> %cmp
+}
More information about the llvm-commits
mailing list