[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