[llvm] [X86] combineINSERT_SUBVECTOR - attempt to widen mask predicate as scalar integer instead of inserting into a zero vXi1 vector (PR #192699)

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 17 09:56:37 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Simon Pilgrim (RKSimon)

<details>
<summary>Changes</summary>

Fold vXi1 insert_subvector(zero_vector(),bitcast(scalar_mask),idx) -> bitcast(shl(zext(scalar_mask),idx))

vXi1 zero widening and insertion has to rely on kshiftl/kshiftr pairs, but if the mask was a scalar it can be a lot cheaper to just widen it to a wider (legal) scalar first.

Cleans up some codegen for #<!-- -->192034 - first step towards pruning all the VMOVSH patterns we've ended up :/

---
Full diff: https://github.com/llvm/llvm-project/pull/192699.diff


6 Files Affected:

- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+14) 
- (modified) llvm/test/CodeGen/X86/masked_gather.ll (+3-4) 
- (modified) llvm/test/CodeGen/X86/masked_gather_scatter.ll (+19-28) 
- (modified) llvm/test/CodeGen/X86/masked_load.ll (+2-3) 
- (modified) llvm/test/CodeGen/X86/masked_store.ll (+2-3) 
- (modified) llvm/test/CodeGen/X86/pr192034.ll (+2-4) 


``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6a00f57e78dd3..56d8060272dc1 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -60935,6 +60935,7 @@ static SDValue combineINSERT_SUBVECTOR(SDNode *N, SelectionDAG &DAG,
   MVT SubVecVT = SubVec.getSimpleValueType();
   int VecNumElts = OpVT.getVectorNumElements();
   int SubVecNumElts = SubVecVT.getVectorNumElements();
+  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
 
   if (Vec.isUndef() && SubVec.isUndef())
     return DAG.getUNDEF(OpVT);
@@ -60972,6 +60973,19 @@ static SDValue combineINSERT_SUBVECTOR(SDNode *N, SelectionDAG &DAG,
                              getZeroVector(OpVT, Subtarget, DAG, dl),
                              Ins.getOperand(1), N->getOperand(2));
     }
+
+    // See if were inserting into a zero vXi1 vector and the subvector was
+    // bitcast from a gpr that could be zero-extended directly.
+    if (IsI1Vector && TLI.isTypeLegal(OpVT)) {
+      SDValue SubInt = peekThroughBitcasts(SubVec);
+      EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), VecNumElts);
+      if (TLI.isTypeLegal(IntVT) && SubInt.getValueType().isScalarInteger()) {
+        SubInt = DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, SubInt);
+        SubInt = DAG.getNode(ISD::SHL, dl, IntVT, SubInt,
+                             DAG.getShiftAmountConstant(IdxVal, IntVT, dl));
+        return DAG.getBitcast(OpVT, SubInt);
+      }
+    }
   }
 
   // Stop here if this is an i1 vector.
diff --git a/llvm/test/CodeGen/X86/masked_gather.ll b/llvm/test/CodeGen/X86/masked_gather.ll
index 2913fe13095ca..d55c09cf4a033 100644
--- a/llvm/test/CodeGen/X86/masked_gather.ll
+++ b/llvm/test/CodeGen/X86/masked_gather.ll
@@ -2576,12 +2576,11 @@ define <8 x i32> @masked_gather_v8i32_v8i32(i8 %trigger) {
 ;
 ; AVX512F-LABEL: masked_gather_v8i32_v8i32:
 ; AVX512F:       # %bb.0:
-; AVX512F-NEXT:    kmovw %edi, %k0
-; AVX512F-NEXT:    kshiftlw $8, %k0, %k0
-; AVX512F-NEXT:    kshiftrw $8, %k0, %k1
+; AVX512F-NEXT:    movzbl %dil, %eax
+; AVX512F-NEXT:    kmovw %eax, %k1
 ; AVX512F-NEXT:    vpxor %xmm0, %xmm0, %xmm0
-; AVX512F-NEXT:    vpxor %xmm1, %xmm1, %xmm1
 ; AVX512F-NEXT:    kmovw %k1, %k2
+; AVX512F-NEXT:    vpxor %xmm1, %xmm1, %xmm1
 ; AVX512F-NEXT:    vpgatherdd c+12(,%zmm0), %zmm1 {%k2}
 ; AVX512F-NEXT:    vpxor %xmm2, %xmm2, %xmm2
 ; AVX512F-NEXT:    vpgatherdd c+28(,%zmm0), %zmm2 {%k1}
diff --git a/llvm/test/CodeGen/X86/masked_gather_scatter.ll b/llvm/test/CodeGen/X86/masked_gather_scatter.ll
index 18e8339b39082..65402bdaf4fae 100644
--- a/llvm/test/CodeGen/X86/masked_gather_scatter.ll
+++ b/llvm/test/CodeGen/X86/masked_gather_scatter.ll
@@ -260,9 +260,8 @@ define <8 x i32> @test7(ptr %base, <8 x i32> %ind, i8 %mask) {
 ; X64-KNL-LABEL: test7:
 ; X64-KNL:       # %bb.0:
 ; X64-KNL-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
-; X64-KNL-NEXT:    kmovw %esi, %k0
-; X64-KNL-NEXT:    kshiftlw $8, %k0, %k0
-; X64-KNL-NEXT:    kshiftrw $8, %k0, %k1
+; X64-KNL-NEXT:    movzbl %sil, %eax
+; X64-KNL-NEXT:    kmovw %eax, %k1
 ; X64-KNL-NEXT:    vpxor %xmm1, %xmm1, %xmm1
 ; X64-KNL-NEXT:    kmovw %k1, %k2
 ; X64-KNL-NEXT:    vpgatherdd (%rdi,%zmm0,4), %zmm1 {%k2}
@@ -274,16 +273,14 @@ define <8 x i32> @test7(ptr %base, <8 x i32> %ind, i8 %mask) {
 ; X86-KNL-LABEL: test7:
 ; X86-KNL:       # %bb.0:
 ; X86-KNL-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
-; X86-KNL-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-KNL-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; X86-KNL-NEXT:    kmovw %ecx, %k0
-; X86-KNL-NEXT:    kshiftlw $8, %k0, %k0
-; X86-KNL-NEXT:    kshiftrw $8, %k0, %k1
+; X86-KNL-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; X86-KNL-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-KNL-NEXT:    kmovw %eax, %k1
 ; X86-KNL-NEXT:    vpxor %xmm1, %xmm1, %xmm1
 ; X86-KNL-NEXT:    kmovw %k1, %k2
-; X86-KNL-NEXT:    vpgatherdd (%eax,%zmm0,4), %zmm1 {%k2}
+; X86-KNL-NEXT:    vpgatherdd (%ecx,%zmm0,4), %zmm1 {%k2}
 ; X86-KNL-NEXT:    vmovdqa %ymm1, %ymm2
-; X86-KNL-NEXT:    vpgatherdd (%eax,%zmm0,4), %zmm1 {%k1}
+; X86-KNL-NEXT:    vpgatherdd (%ecx,%zmm0,4), %zmm1 {%k1}
 ; X86-KNL-NEXT:    vpaddd %ymm1, %ymm2, %ymm0
 ; X86-KNL-NEXT:    retl
 ;
@@ -4702,9 +4699,8 @@ define void @scaleidx_scatter(<8 x float> %value, ptr %base, <8 x i32> %index, i
 ; X64-KNL:       # %bb.0:
 ; X64-KNL-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
 ; X64-KNL-NEXT:    vpaddd %ymm1, %ymm1, %ymm1
-; X64-KNL-NEXT:    kmovw %esi, %k0
-; X64-KNL-NEXT:    kshiftlw $8, %k0, %k0
-; X64-KNL-NEXT:    kshiftrw $8, %k0, %k1
+; X64-KNL-NEXT:    movzbl %sil, %eax
+; X64-KNL-NEXT:    kmovw %eax, %k1
 ; X64-KNL-NEXT:    vscatterdps %zmm0, (%rdi,%zmm1,4) {%k1}
 ; X64-KNL-NEXT:    vzeroupper
 ; X64-KNL-NEXT:    retq
@@ -4712,13 +4708,11 @@ define void @scaleidx_scatter(<8 x float> %value, ptr %base, <8 x i32> %index, i
 ; X86-KNL-LABEL: scaleidx_scatter:
 ; X86-KNL:       # %bb.0:
 ; X86-KNL-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
-; X86-KNL-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-KNL-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; X86-KNL-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-KNL-NEXT:    vpaddd %ymm1, %ymm1, %ymm1
-; X86-KNL-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; X86-KNL-NEXT:    kmovw %ecx, %k0
-; X86-KNL-NEXT:    kshiftlw $8, %k0, %k0
-; X86-KNL-NEXT:    kshiftrw $8, %k0, %k1
-; X86-KNL-NEXT:    vscatterdps %zmm0, (%eax,%zmm1,4) {%k1}
+; X86-KNL-NEXT:    kmovw %eax, %k1
+; X86-KNL-NEXT:    vscatterdps %zmm0, (%ecx,%zmm1,4) {%k1}
 ; X86-KNL-NEXT:    vzeroupper
 ; X86-KNL-NEXT:    retl
 ;
@@ -4749,9 +4743,8 @@ define void @scaleidx_scatter_outofrange(<8 x float> %value, ptr %base, <8 x i32
 ; X64-KNL:       # %bb.0:
 ; X64-KNL-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
 ; X64-KNL-NEXT:    vpslld $2, %ymm1, %ymm1
-; X64-KNL-NEXT:    kmovw %esi, %k0
-; X64-KNL-NEXT:    kshiftlw $8, %k0, %k0
-; X64-KNL-NEXT:    kshiftrw $8, %k0, %k1
+; X64-KNL-NEXT:    movzbl %sil, %eax
+; X64-KNL-NEXT:    kmovw %eax, %k1
 ; X64-KNL-NEXT:    vscatterdps %zmm0, (%rdi,%zmm1,4) {%k1}
 ; X64-KNL-NEXT:    vzeroupper
 ; X64-KNL-NEXT:    retq
@@ -4759,13 +4752,11 @@ define void @scaleidx_scatter_outofrange(<8 x float> %value, ptr %base, <8 x i32
 ; X86-KNL-LABEL: scaleidx_scatter_outofrange:
 ; X86-KNL:       # %bb.0:
 ; X86-KNL-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
-; X86-KNL-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-KNL-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; X86-KNL-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-KNL-NEXT:    vpslld $2, %ymm1, %ymm1
-; X86-KNL-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; X86-KNL-NEXT:    kmovw %ecx, %k0
-; X86-KNL-NEXT:    kshiftlw $8, %k0, %k0
-; X86-KNL-NEXT:    kshiftrw $8, %k0, %k1
-; X86-KNL-NEXT:    vscatterdps %zmm0, (%eax,%zmm1,4) {%k1}
+; X86-KNL-NEXT:    kmovw %eax, %k1
+; X86-KNL-NEXT:    vscatterdps %zmm0, (%ecx,%zmm1,4) {%k1}
 ; X86-KNL-NEXT:    vzeroupper
 ; X86-KNL-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/masked_load.ll b/llvm/test/CodeGen/X86/masked_load.ll
index 99a8918fef93f..d755c8e34e60b 100644
--- a/llvm/test/CodeGen/X86/masked_load.ll
+++ b/llvm/test/CodeGen/X86/masked_load.ll
@@ -1861,9 +1861,8 @@ define <8 x float> @load_v8f32_i8(i8 %trigger, ptr %addr) {
 ;
 ; AVX512F-LABEL: load_v8f32_i8:
 ; AVX512F:       ## %bb.0:
-; AVX512F-NEXT:    kmovw %edi, %k0
-; AVX512F-NEXT:    kshiftlw $8, %k0, %k0
-; AVX512F-NEXT:    kshiftrw $8, %k0, %k1
+; AVX512F-NEXT:    movzbl %dil, %eax
+; AVX512F-NEXT:    kmovw %eax, %k1
 ; AVX512F-NEXT:    vmovups (%rsi), %zmm0 {%k1} {z}
 ; AVX512F-NEXT:    ## kill: def $ymm0 killed $ymm0 killed $zmm0
 ; AVX512F-NEXT:    retq
diff --git a/llvm/test/CodeGen/X86/masked_store.ll b/llvm/test/CodeGen/X86/masked_store.ll
index bdbb912a71d36..3e35df97be6df 100644
--- a/llvm/test/CodeGen/X86/masked_store.ll
+++ b/llvm/test/CodeGen/X86/masked_store.ll
@@ -992,9 +992,8 @@ define void @store_v8f32_i8(<8 x float> %x, ptr %ptr, <8 x float> %y, i8 %trigge
 ; AVX512F-LABEL: store_v8f32_i8:
 ; AVX512F:       ## %bb.0:
 ; AVX512F-NEXT:    ## kill: def $ymm0 killed $ymm0 def $zmm0
-; AVX512F-NEXT:    kmovw %esi, %k0
-; AVX512F-NEXT:    kshiftlw $8, %k0, %k0
-; AVX512F-NEXT:    kshiftrw $8, %k0, %k1
+; AVX512F-NEXT:    movzbl %sil, %eax
+; AVX512F-NEXT:    kmovw %eax, %k1
 ; AVX512F-NEXT:    vmovups %zmm0, (%rdi) {%k1}
 ; AVX512F-NEXT:    vzeroupper
 ; AVX512F-NEXT:    retq
diff --git a/llvm/test/CodeGen/X86/pr192034.ll b/llvm/test/CodeGen/X86/pr192034.ll
index 67d3ff27ef596..8965d6166d018 100644
--- a/llvm/test/CodeGen/X86/pr192034.ll
+++ b/llvm/test/CodeGen/X86/pr192034.ll
@@ -18,10 +18,8 @@ define <8 x half> @maskload_v8f16_byref(ptr %p, i8 %k, ptr %mem_addr) {
 ; CHECK-LABEL: maskload_v8f16_byref:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero
-; CHECK-NEXT:    andb $1, %sil
-; CHECK-NEXT:    kmovd %esi, %k0
-; CHECK-NEXT:    kshiftld $24, %k0, %k0
-; CHECK-NEXT:    kshiftrd $24, %k0, %k1
+; CHECK-NEXT:    andl $1, %esi
+; CHECK-NEXT:    kmovd %esi, %k1
 ; CHECK-NEXT:    vmovdqu16 (%rdx), %zmm0 {%k1}
 ; CHECK-NEXT:    # kill: def $xmm0 killed $xmm0 killed $zmm0
 ; CHECK-NEXT:    vzeroupper

``````````

</details>


https://github.com/llvm/llvm-project/pull/192699


More information about the llvm-commits mailing list