[llvm] 2ef17d9 - [DAG] Optimize masked store of constant lane mask to standard store (#224255)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 00:22:27 PDT 2026


Author: David Green
Date: 2026-09-21T08:22:21+01:00
New Revision: 2ef17d9c2d8090771aecac3e2e0738eeedd38768

URL: https://github.com/llvm/llvm-project/commit/2ef17d9c2d8090771aecac3e2e0738eeedd38768
DIFF: https://github.com/llvm/llvm-project/commit/2ef17d9c2d8090771aecac3e2e0738eeedd38768.diff

LOG: [DAG] Optimize masked store of constant lane mask to standard store (#224255)

A masked store with a constant mask enabling the first n lanes can be
lowered to a standard store of size n.

For example a masked store with masks `<1, 1, 0, 0>` or a scalable store
with mask `llvm.get.active.lane.mask.v4i1.i32(i32 0, i32 2)`

This is a recommit of #223665 with a legal type check to protect against
v1f64 stores on X86 with +avx512.

Added: 
    llvm/test/CodeGen/X86/masked-store-illegal-type.ll

Modified: 
    llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/test/CodeGen/AArch64/lowmaskedlanes.ll
    llvm/test/CodeGen/Hexagon/autohvx/vector-align-basic.ll
    llvm/test/CodeGen/X86/apx/kmov-postrapseudos.ll
    llvm/test/CodeGen/X86/pr179489.ll
    llvm/test/CodeGen/X86/pr46532.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b70c7e8d4c1e4..771e4a99111c8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -13901,12 +13901,47 @@ SDValue DAGCombiner::visitMSCATTER(SDNode *N) {
   return SDValue();
 }
 
+/// Check if Mask defines a known constant set of enabled lanes, where only the
+/// first N lanes are enabled. N is returned if so.
+static uint64_t calculateConstantLowMaskLanes(SDValue Mask) {
+  // We expect masks for masked load/store to be i1 predicates.
+  if (Mask.getValueType().getScalarSizeInBits() != 1)
+    return 0;
+
+  if (Mask.getOpcode() == ISD::BUILD_VECTOR) {
+    unsigned NumOnes = 0;
+    auto Op = Mask->op_begin();
+    for (; Op != Mask->op_end(); ++Op) {
+      if (!isOneConstant(*Op))
+        break;
+      ++NumOnes;
+    }
+
+    if (NumOnes == 0)
+      return 0;
+
+    for (; Op != Mask->op_end(); ++Op)
+      if (!isNullConstant(*Op))
+        return 0;
+    return NumOnes;
+  }
+
+  if (Mask.getOpcode() == ISD::GET_ACTIVE_LANE_MASK &&
+      isNullConstant(Mask.getOperand(0)) &&
+      isa<ConstantSDNode>(Mask.getOperand(1)) &&
+      Mask.getOperand(1).getValueType().getSizeInBits() <= 64)
+    return Mask.getConstantOperandVal(1);
+
+  return 0;
+}
+
 SDValue DAGCombiner::visitMSTORE(SDNode *N) {
   MaskedStoreSDNode *MST = cast<MaskedStoreSDNode>(N);
   SDValue Mask = MST->getMask();
   SDValue Chain = MST->getChain();
   SDValue Value = MST->getValue();
   SDValue Ptr = MST->getBasePtr();
+  EVT VT = Value.getValueType();
 
   // Zap masked stores with a zero mask.
   if (ISD::isConstantSplatVectorAllZeros(Mask.getNode()))
@@ -13929,21 +13964,46 @@ SDValue DAGCombiner::visitMSTORE(SDNode *N) {
     }
   }
 
-  // If this is a masked load with an all ones mask, we can use a unmasked load.
+  // If this is a masked store with an all ones mask, we can use a unmasked
+  // store.
   // FIXME: Can we do this for indexed, compressing, or truncating stores?
-  if (ISD::isConstantSplatVectorAllOnes(Mask.getNode()) && MST->isUnindexed() &&
-      !MST->isCompressingStore() && !MST->isTruncatingStore())
-    return DAG.getStore(MST->getChain(), SDLoc(N), MST->getValue(),
-                        MST->getBasePtr(), MST->getPointerInfo(),
-                        MST->getBaseAlign(), MST->getMemOperand()->getFlags(),
-                        MST->getAAInfo());
+  if (MST->isUnindexed() && !MST->isCompressingStore() &&
+      !MST->isTruncatingStore()) {
+    if (ISD::isConstantSplatVectorAllOnes(Mask.getNode()))
+      return DAG.getStore(MST->getChain(), SDLoc(N), MST->getValue(),
+                          MST->getBasePtr(), MST->getPointerInfo(),
+                          MST->getBaseAlign(), MST->getMemOperand()->getFlags(),
+                          MST->getAAInfo());
+
+    // Convert a masked_store with constant getactivelanemask input mask to a
+    // standard store.
+    if (uint64_t Lanes = calculateConstantLowMaskLanes(Mask)) {
+      if (Lanes < VT.getVectorMinNumElements() && isPowerOf2_32(Lanes)) {
+        EVT SubVT = EVT::getVectorVT(*DAG.getContext(),
+                                     VT.getVectorElementType(), Lanes);
+        unsigned IsFast = 0;
+        if ((!LegalTypes || isTypeLegal(SubVT)) &&
+            TLI.allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(),
+                                   SubVT, MST->getAddressSpace(),
+                                   MST->getBaseAlign(),
+                                   MST->getMemOperand()->getFlags(), &IsFast) &&
+            IsFast) {
+          SDLoc DL(N);
+          SDValue Ext = DAG.getExtractSubvector(DL, SubVT, MST->getValue(), 0);
+          return DAG.getStore(MST->getChain(), DL, Ext, MST->getBasePtr(),
+                              MST->getPointerInfo(), MST->getBaseAlign(),
+                              MST->getMemOperand()->getFlags(),
+                              MST->getAAInfo());
+        }
+      }
+    }
+  }
 
   // Try transforming N to an indexed store.
   if (CombineToPreIndexedLoadStore(N) || CombineToPostIndexedLoadStore(N))
     return SDValue(N, 0);
 
-  if (MST->isTruncatingStore() && MST->isUnindexed() &&
-      Value.getValueType().isInteger() &&
+  if (MST->isTruncatingStore() && MST->isUnindexed() && VT.isInteger() &&
       (!isa<ConstantSDNode>(Value) ||
        !cast<ConstantSDNode>(Value)->isOpaque())) {
     APInt TruncDemandedBits =

diff  --git a/llvm/test/CodeGen/AArch64/lowmaskedlanes.ll b/llvm/test/CodeGen/AArch64/lowmaskedlanes.ll
index 99905726a5cf4..1a3f88ef11b33 100644
--- a/llvm/test/CodeGen/AArch64/lowmaskedlanes.ll
+++ b/llvm/test/CodeGen/AArch64/lowmaskedlanes.ll
@@ -139,14 +139,7 @@ define <vscale x 8 x i16> @load_low4_nxv8i16(ptr %p) {
 define void @store_low2_v4f64(ptr %p, <4 x double> %a) vscale_range(2, 2) {
 ; CHECK-LABEL: store_low2_v4f64:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    // kill: def $q1 killed $q1 killed $z0_z1 def $z0_z1
-; CHECK-NEXT:    ptrue p0.d, vl2
-; CHECK-NEXT:    ptrue p1.h, vl2
-; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0_z1 def $z0_z1
-; CHECK-NEXT:    splice z0.d, p0, { z0.d, z1.d }
-; CHECK-NEXT:    punpklo p0.h, p1.b
-; CHECK-NEXT:    punpklo p0.h, p0.b
-; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
+; CHECK-NEXT:    str q0, [x0]
 ; CHECK-NEXT:    ret
   %m = tail call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 0, i32 2)
   tail call void @llvm.masked.store(<4 x double> %a, ptr align 1 %p, <4 x i1> %m)
@@ -156,13 +149,7 @@ define void @store_low2_v4f64(ptr %p, <4 x double> %a) vscale_range(2, 2) {
 define void @store_low2_v4i32(ptr %p, <4 x i32> %a) vscale_range(1, 1) {
 ; CHECK-LABEL: store_low2_v4i32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.h, vl2
-; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
-; CHECK-NEXT:    mov z1.h, p0/z, #-1 // =0xffffffffffffffff
-; CHECK-NEXT:    ptrue p0.s
-; CHECK-NEXT:    sshll v1.4s, v1.4h, #0
-; CHECK-NEXT:    cmpne p1.s, p0/z, z1.s, #0
-; CHECK-NEXT:    st1w { z0.s }, p1, [x0]
+; CHECK-NEXT:    str d0, [x0]
 ; CHECK-NEXT:    ret
   %m = tail call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 0, i32 2)
   tail call void @llvm.masked.store(<4 x i32> %a, ptr align 1 %p, <4 x i1> %m)
@@ -172,12 +159,7 @@ define void @store_low2_v4i32(ptr %p, <4 x i32> %a) vscale_range(1, 1) {
 define void @store_low2c_v4i32(ptr %p, <4 x i32> %a) vscale_range(1, 1) {
 ; CHECK-LABEL: store_low2c_v4i32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    adrp x8, .LCPI12_0
-; CHECK-NEXT:    ptrue p0.s
-; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
-; CHECK-NEXT:    ldr q1, [x8, :lo12:.LCPI12_0]
-; CHECK-NEXT:    cmpne p1.s, p0/z, z1.s, #0
-; CHECK-NEXT:    st1w { z0.s }, p1, [x0]
+; CHECK-NEXT:    str d0, [x0]
 ; CHECK-NEXT:    ret
   tail call void @llvm.masked.store(<4 x i32> %a, ptr align 1 %p, <4 x i1> <i1 true, i1 true, i1 false, i1 false>)
   ret void
@@ -186,11 +168,7 @@ define void @store_low2c_v4i32(ptr %p, <4 x i32> %a) vscale_range(1, 1) {
 define void @store_low2_nxv4f64(ptr %p, <vscale x 4 x double> %a) {
 ; CHECK-LABEL: store_low2_nxv4f64:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.s, vl2
-; CHECK-NEXT:    punpkhi p1.h, p0.b
-; CHECK-NEXT:    punpklo p0.h, p0.b
-; CHECK-NEXT:    st1d { z1.d }, p1, [x0, #1, mul vl]
-; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
+; CHECK-NEXT:    str q0, [x0]
 ; CHECK-NEXT:    ret
   %m = tail call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i32(i32 0, i32 2)
   tail call void @llvm.masked.store(<vscale x 4 x double> %a, ptr align 1 %p, <vscale x 4 x i1> %m)
@@ -225,13 +203,10 @@ define void @store_low4_nxv4f64(ptr %p, <vscale x 4 x double> %a) {
 define void @store_low2_v8i16(ptr %p, <8 x i16> %a) vscale_range(2, 2) {
 ; CHECK-LABEL: store_low2_v8i16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.b, vl2
 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
-; CHECK-NEXT:    mov z1.b, p0/z, #-1 // =0xffffffffffffffff
-; CHECK-NEXT:    ptrue p0.h, vl8
-; CHECK-NEXT:    sshll v1.8h, v1.8b, #0
-; CHECK-NEXT:    cmpne p1.h, p0/z, z1.h, #0
-; CHECK-NEXT:    st1h { z0.h }, p1, [x0]
+; CHECK-NEXT:    ptrue p0.s, vl2
+; CHECK-NEXT:    uunpklo z0.s, z0.h
+; CHECK-NEXT:    st1h { z0.s }, p0, [x0]
 ; CHECK-NEXT:    ret
   %m = tail call <8 x i1> @llvm.get.active.lane.mask.v8i1.i32(i32 0, i32 2)
   tail call void @llvm.masked.store(<8 x i16> %a, ptr align 1 %p, <8 x i1> %m)
@@ -241,8 +216,9 @@ define void @store_low2_v8i16(ptr %p, <8 x i16> %a) vscale_range(2, 2) {
 define void @store_low2_nxv8i16(ptr %p, <vscale x 8 x i16> %a) {
 ; CHECK-LABEL: store_low2_nxv8i16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.h, vl2
-; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
+; CHECK-NEXT:    mov z1.h, z0.h[1]
+; CHECK-NEXT:    str h0, [x0]
+; CHECK-NEXT:    str h1, [x0, #2]
 ; CHECK-NEXT:    ret
   %m = tail call <vscale x 8 x i1> @llvm.get.active.lane.mask.nxv8i1.i32(i32 0, i32 2)
   tail call void @llvm.masked.store(<vscale x 8 x i16> %a, ptr align 1 %p, <vscale x 8 x i1> %m)
@@ -263,8 +239,7 @@ define void @store_low2_nxv2i16(ptr %p, <vscale x 2 x i16> %a) {
 define void @store_low4_nxv8i16(ptr %p, <vscale x 8 x i16> %a) {
 ; CHECK-LABEL: store_low4_nxv8i16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.h, vl4
-; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
+; CHECK-NEXT:    str d0, [x0]
 ; CHECK-NEXT:    ret
   %m = tail call <vscale x 8 x i1> @llvm.get.active.lane.mask.nxv8i1.i32(i32 0, i32 4)
   tail call void @llvm.masked.store(<vscale x 8 x i16> %a, ptr align 1 %p, <vscale x 8 x i1> %m)

diff  --git a/llvm/test/CodeGen/Hexagon/autohvx/vector-align-basic.ll b/llvm/test/CodeGen/Hexagon/autohvx/vector-align-basic.ll
index bc3323ab21912..8dddb042c8255 100644
--- a/llvm/test/CodeGen/Hexagon/autohvx/vector-align-basic.ll
+++ b/llvm/test/CodeGen/Hexagon/autohvx/vector-align-basic.ll
@@ -6,40 +6,43 @@ define <32 x i32> @f0(ptr %a0, i32 %a1) #0 {
 ; CHECK-LABEL: f0:
 ; CHECK:       // %bb.0: // %b0
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[RADD:[r0-9]+]] = add([[R1:[r0-9]+]],[[R0:[r0-9]+]])
+; CHECK-NEXT:     r0 = add(r1,r0)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[RLCPI:[r0-9]+]] = ##.LCPI0_0
+; CHECK-NEXT:     allocframe(r29,#128):raw
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[RNEG:[r0-9]+]] = #-1
+; CHECK-NEXT:     r2 = add(r0,#136)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[RADD136:[r0-9]+]] = add([[RADD]],#136)
+; CHECK-NEXT:     r29 = and(r29,#-128)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[V1:[v0-9]+]] = vmem([[RLCPI]]+#0)
+; CHECK-NEXT:     v1 = vmem(r0+#1)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[RADD128:[r0-9]+]] = add([[RADD]],#128)
+; CHECK-NEXT:     v0 = vmemu(r2+#0)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[Q0:[q0-9]+]] = vand([[V1]],[[RNEG]])
+; CHECK-NEXT:     r4 = add(r29,#0)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[V2:[v0-9]+]] = vmemu([[RADD136]]+#0)
+; CHECK-NEXT:     v0.w = vadd(v1.w,v0.w)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[V3:[v0-9]+]] = vmem([[RADD]]+#1)
+; CHECK-NEXT:     vmem(r4+#0) = v0
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     [[V0:[v0-9]+]].w = vadd([[V3]].w,[[V2]].w)
+; CHECK-NEXT:     r2 = memw(r4+#0)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     if ([[Q0]]) vmem([[RADD128]]+#0) = [[V0]]
+; CHECK-NEXT:     r3 = memw(r4+#4)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     jumpr r31
+; CHECK-NEXT:     memd(r0+#128) = r3:2
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     r31:30 = dealloc_return(r30):raw
 ; CHECK-NEXT:    }
 b0:
   %v0 = add i32 %a1, 128

diff  --git a/llvm/test/CodeGen/X86/apx/kmov-postrapseudos.ll b/llvm/test/CodeGen/X86/apx/kmov-postrapseudos.ll
index fd811b0bbfc4e..45c597a533327 100644
--- a/llvm/test/CodeGen/X86/apx/kmov-postrapseudos.ll
+++ b/llvm/test/CodeGen/X86/apx/kmov-postrapseudos.ll
@@ -29,20 +29,12 @@ entry:
 define void @kmovkr_2() {
 ; AVX512-LABEL: kmovkr_2:
 ; AVX512:       # %bb.0: # %alloca_21
-; AVX512-NEXT:    vxorps %xmm0, %xmm0, %xmm0 # encoding: [0xc5,0xf8,0x57,0xc0]
-; AVX512-NEXT:    movw $3, %ax # encoding: [0x66,0xb8,0x03,0x00]
-; AVX512-NEXT:    kmovw %eax, %k1 # EVEX TO VEX Compression encoding: [0xc5,0xf8,0x92,0xc8]
-; AVX512-NEXT:    vmovups %zmm0, 0 {%k1} # encoding: [0x62,0xf1,0x7c,0x49,0x11,0x04,0x25,0x00,0x00,0x00,0x00]
-; AVX512-NEXT:    vzeroupper # encoding: [0xc5,0xf8,0x77]
+; AVX512-NEXT:    movq $0, 0 # encoding: [0x48,0xc7,0x04,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
 ; AVX512-NEXT:    retq # encoding: [0xc3]
 ;
 ; AVX512BW-LABEL: kmovkr_2:
 ; AVX512BW:       # %bb.0: # %alloca_21
-; AVX512BW-NEXT:    vxorps %xmm0, %xmm0, %xmm0 # encoding: [0xc5,0xf8,0x57,0xc0]
-; AVX512BW-NEXT:    movw $3, %ax # encoding: [0x66,0xb8,0x03,0x00]
-; AVX512BW-NEXT:    kmovd %eax, %k1 # EVEX TO VEX Compression encoding: [0xc5,0xfb,0x92,0xc8]
-; AVX512BW-NEXT:    vmovups %zmm0, 0 {%k1} # encoding: [0x62,0xf1,0x7c,0x49,0x11,0x04,0x25,0x00,0x00,0x00,0x00]
-; AVX512BW-NEXT:    vzeroupper # encoding: [0xc5,0xf8,0x77]
+; AVX512BW-NEXT:    movq $0, 0 # encoding: [0x48,0xc7,0x04,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
 ; AVX512BW-NEXT:    retq # encoding: [0xc3]
 alloca_21:
   call void @llvm.masked.store.v4f32.p0(<4 x float> zeroinitializer, ptr null, i32 1, <4 x i1> <i1 true, i1 true, i1 false, i1 false>)

diff  --git a/llvm/test/CodeGen/X86/masked-store-illegal-type.ll b/llvm/test/CodeGen/X86/masked-store-illegal-type.ll
new file mode 100644
index 0000000000000..c2b098c502dc7
--- /dev/null
+++ b/llvm/test/CodeGen/X86/masked-store-illegal-type.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -mattr=+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl | FileCheck %s
+
+define fastcc void @render_event(<12 x double> %0) {
+; CHECK-LABEL: render_event:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vmovlhps {{.*#+}} xmm6 = xmm6[0],xmm7[0]
+; CHECK-NEXT:    vmovlhps {{.*#+}} xmm4 = xmm4[0],xmm5[0]
+; CHECK-NEXT:    vinsertf128 $1, %xmm6, %ymm4, %ymm4
+; CHECK-NEXT:    vmovlhps {{.*#+}} xmm2 = xmm2[0],xmm3[0]
+; CHECK-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; CHECK-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
+; CHECK-NEXT:    vinsertf64x4 $1, %ymm4, %zmm0, %zmm0
+; CHECK-NEXT:    vmovsd {{.*#+}} xmm1 = mem[0],zero
+; CHECK-NEXT:    vmovsd %xmm1, 64
+; CHECK-NEXT:    vmovups %zmm0, 0
+; CHECK-NEXT:    vzeroupper
+; CHECK-NEXT:    retq
+  call void @llvm.masked.store.v12f64.p0(<12 x double> %0, ptr null, <12 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false>)
+  ret void
+}

diff  --git a/llvm/test/CodeGen/X86/pr179489.ll b/llvm/test/CodeGen/X86/pr179489.ll
index b7308b77669e7..f610cdf2ce7cb 100644
--- a/llvm/test/CodeGen/X86/pr179489.ll
+++ b/llvm/test/CodeGen/X86/pr179489.ll
@@ -9,14 +9,12 @@ define void @foo(<8 x i16> %arg, ptr addrspace(1) %add.ptr) {
 ; X86-LABEL: foo:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    vmovw %xmm0, %ecx
-; X86-NEXT:    movb %ch, (%eax)
+; X86-NEXT:    vpextrb $1, %xmm0, (%eax)
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: foo:
 ; X64:       # %bb.0: # %entry
-; X64-NEXT:    vmovw %xmm0, %eax
-; X64-NEXT:    movb %ah, (%rdi)
+; X64-NEXT:    vpextrb $1, %xmm0, (%rdi)
 ; X64-NEXT:    retq
 entry:
   %i3 = shufflevector <8 x i16> %arg, <8 x i16> <i16 poison, i16 257, i16 257, i16 257, i16 257, i16 257, i16 257, i16 257>, <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>

diff  --git a/llvm/test/CodeGen/X86/pr46532.ll b/llvm/test/CodeGen/X86/pr46532.ll
index cbc677229ede6..ea11a0eec42e0 100644
--- a/llvm/test/CodeGen/X86/pr46532.ll
+++ b/llvm/test/CodeGen/X86/pr46532.ll
@@ -7,8 +7,6 @@ define void @WhileWithLoopInvariantOperation.21() {
 ; CHECK-NEXT:    movq (%rax), %rax
 ; CHECK-NEXT:    vxorps %xmm0, %xmm0, %xmm0
 ; CHECK-NEXT:    vmovaps %xmm0, 32(%rax)
-; CHECK-NEXT:    vmovsd {{.*#+}} xmm0 = [4294967295,4294967295,0,0]
-; CHECK-NEXT:    vmaskmovps %ymm0, %ymm0, (%rax)
 while.1.body.preheader:
   %0 = load ptr, ptr undef, align 8, !invariant.load !0, !dereferenceable !1, !align !2
   %1 = getelementptr inbounds i8, ptr %0, i64 32


        


More information about the llvm-commits mailing list