[llvm] [X86] Fold broadcast(truncate(extract_vector_elt(x, 0))) -> bitcast(broadcast(x)) (PR #206461)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 04:00:07 PDT 2026


https://github.com/RKSimon created https://github.com/llvm/llvm-project/pull/206461

Fixes regressions in #205098

>From 66d3199a766167ea00127ff4ab57b8157f9263dc Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 29 Jun 2026 11:58:44 +0100
Subject: [PATCH] [X86] Fold broadcast(truncate(extract_vector_elt(x, 0))) ->
 bitcast(broadcast(x))

Fixes regressions in #205098
---
 llvm/lib/Target/X86/X86ISelLowering.cpp     | 16 ++++++++++++++++
 llvm/test/CodeGen/X86/combine-reductions.ll |  1 -
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index b95ac78f50049..0628aa6baaa7e 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -43288,6 +43288,22 @@ static SDValue combineTargetShuffle(SDValue N, const SDLoc &DL,
         TLI.isTypeLegal(Src.getOperand(0).getValueType()))
       return DAG.getNode(X86ISD::VBROADCAST, DL, VT, Src.getOperand(0));
 
+    // broadcast(truncate(extract_vector_elt(x, 0))) -> bitcast(broadcast(x)).
+    if (Src.getOpcode() == ISD::TRUNCATE &&
+        Src.getOperand(0).getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
+        isNullConstant(Src.getOperand(0).getOperand(1))) {
+      SDValue NewSrc = Src.getOperand(0).getOperand(0);
+      if (Src.getOperand(0).getValueType() ==
+              NewSrc.getValueType().getScalarType() &&
+          TLI.isTypeLegal(NewSrc.getValueType())) {
+        MVT VecVT = MVT::getVectorVT(Src.getSimpleValueType(),
+                                     NewSrc.getValueSizeInBits() /
+                                         Src.getValueSizeInBits());
+        return DAG.getNode(X86ISD::VBROADCAST, DL, VT,
+                           DAG.getBitcast(VecVT, NewSrc));
+      }
+    }
+
     // Share broadcast with the longest vector and extract low subvector (free).
     // Ensure the same SDValue from the SDNode use is being used.
     for (SDNode *User : Src->users())
diff --git a/llvm/test/CodeGen/X86/combine-reductions.ll b/llvm/test/CodeGen/X86/combine-reductions.ll
index 844cd13e71d49..5f59cce91e2a3 100644
--- a/llvm/test/CodeGen/X86/combine-reductions.ll
+++ b/llvm/test/CodeGen/X86/combine-reductions.ll
@@ -33,7 +33,6 @@ define { i16, i16 } @test_reduce_v16i16_with_umin(<16 x i16> %x, <16 x i16> %y)
 ; AVX2-NEXT:    vpminuw %xmm2, %xmm0, %xmm2
 ; AVX2-NEXT:    vphminposuw %xmm2, %xmm2
 ; AVX2-NEXT:    vmovd %xmm2, %eax
-; AVX2-NEXT:    vmovd %eax, %xmm2
 ; AVX2-NEXT:    vpbroadcastw %xmm2, %ymm2
 ; AVX2-NEXT:    vpcmpeqw %ymm2, %ymm0, %ymm0
 ; AVX2-NEXT:    vpcmpeqd %ymm2, %ymm2, %ymm2



More information about the llvm-commits mailing list