[llvm] [X86] Optimize lowering of single-element load BUILD_VECTOR for pre-SSE4.1 (PR #217731)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 11:49:58 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: AZero13 (AZero13)
<details>
<summary>Changes</summary>
This PR optimizes the lowering of 128-bit `BUILD_VECTOR` operations that insert a single scalar load into an otherwise zero-initialized vector (e.g., the pattern generated by `_mm_set_ps(0, 0, x, 0)`).
---
Full diff: https://github.com/llvm/llvm-project/pull/217731.diff
2 Files Affected:
- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+27-4)
- (modified) llvm/test/CodeGen/X86/vector-shuffle-combining.ll (+4-6)
``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index bf435b0c2f849..375aace096c82 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -9668,12 +9668,35 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
// Otherwise, if this is a vector with i32 or f32 elements, and the element
// is a non-constant being inserted into an element other than the low one,
- // we can't use a constant pool load. Instead, use SCALAR_TO_VECTOR (aka
- // movd/movss) to move this into the low element, then shuffle it into
- // place.
+ // we can't use a constant pool load.
if (EVTBits == 32) {
+ // If the element is a load, we can emit a VZEXT_LOAD to zero-extend the
+ // scalar into a 128-bit vector, and then shuffle the element into place.
+ // This avoids emitting a separate zero vector and cross-domain penalties.
+ if (!Subtarget.hasSSE41() && NumZero > 0 &&
+ Item.getOpcode() == ISD::LOAD && Item.hasOneUse() &&
+ VT.is128BitVector() &&
+ cast<LoadSDNode>(Item)->getMemoryVT().getSizeInBits() == 32) {
+ auto *LN = cast<LoadSDNode>(Item);
+ SDVTList Tys = DAG.getVTList(VT, MVT::Other);
+ SDValue Ops[] = {LN->getChain(), LN->getBasePtr()};
+ SDValue VZLoad = DAG.getMemIntrinsicNode(
+ X86ISD::VZEXT_LOAD, dl, Tys, Ops, LN->getMemoryVT(),
+ LN->getPointerInfo(), LN->getBaseAlign(),
+ LN->getMemOperand()->getFlags());
+ DAG.makeEquivalentMemoryOrdering(LN, VZLoad);
+ SmallVector<int, 16> MaskVec(NumElems);
+ for (unsigned i = 0; i != NumElems; ++i)
+ MaskVec[i] = (i == Idx) ? 0 : 1;
+ return DAG.getVectorShuffle(VT, dl, VZLoad, VZLoad, MaskVec);
+ }
+
+ // For non-loads (or if the VZEXT_LOAD path isn't applicable), we fallback
+ // to using SCALAR_TO_VECTOR (aka movd/movss) to move this into the low
+ // element, then shuffle it into place.
Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Item);
- return getShuffleVectorZeroOrUndef(Item, Idx, NumZero > 0, Subtarget, DAG);
+ return getShuffleVectorZeroOrUndef(Item, Idx, NumZero > 0, Subtarget,
+ DAG);
}
}
diff --git a/llvm/test/CodeGen/X86/vector-shuffle-combining.ll b/llvm/test/CodeGen/X86/vector-shuffle-combining.ll
index f31c1d5667f2f..3013bdd6f2bdc 100644
--- a/llvm/test/CodeGen/X86/vector-shuffle-combining.ll
+++ b/llvm/test/CodeGen/X86/vector-shuffle-combining.ll
@@ -3626,19 +3626,17 @@ define <8 x float> @PR213251() {
; SSE2-LABEL: PR213251:
; SSE2: # %bb.0:
; SSE2-NEXT: movl $1, (%rax)
-; SSE2-NEXT: movd {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]
-; SSE2-NEXT: movq {{.*#+}} xmm0 = xmm0[0],zero
+; SSE2-NEXT: movss {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]
+; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0,1,1]
; SSE2-NEXT: xorps %xmm1, %xmm1
-; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
; SSE2-NEXT: retq
;
; SSSE3-LABEL: PR213251:
; SSSE3: # %bb.0:
; SSSE3-NEXT: movl $1, (%rax)
-; SSSE3-NEXT: movd {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]
-; SSSE3-NEXT: movq {{.*#+}} xmm0 = xmm0[0],zero
+; SSSE3-NEXT: movss {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]
+; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0,1,1]
; SSSE3-NEXT: xorps %xmm1, %xmm1
-; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
; SSSE3-NEXT: retq
;
; SSE41-LABEL: PR213251:
``````````
</details>
https://github.com/llvm/llvm-project/pull/217731
More information about the llvm-commits
mailing list