[llvm] 68fddbb - [DAG] Scalarise trivial splat operations (#226257)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 27 05:02:31 PDT 2026


Author: David Green
Date: 2026-09-27T13:02:24+01:00
New Revision: 68fddbbe019b63698e9c4a898b313b9112019cab

URL: https://github.com/llvm/llvm-project/commit/68fddbbe019b63698e9c4a898b313b9112019cab
DIFF: https://github.com/llvm/llvm-project/commit/68fddbbe019b63698e9c4a898b313b9112019cab.diff

LOG: [DAG] Scalarise trivial splat operations (#226257)

This fixes an issue reported on #224255, where a single active lane
masked store is converted to a v1f16 extract_subvector, which becomes a
v1f16 splat, which fails to scalarize. Add the necessary trivial
scalarisation of the splat by using the f16 input operand.

(I was originally going to fix this by generating a scalar f16 extract
directly (which would have the benefit of treating f16 as legal), but
that seems to cause a regression in 2 x86 tests).

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
    llvm/test/CodeGen/AArch64/lowmaskedlanes.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index b638d00673490..0cf31089e08bd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -837,7 +837,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
 
   SDValue ScalarizeVecRes_ADDRSPACECAST(SDNode *N);
   SDValue ScalarizeVecRes_BITCAST(SDNode *N);
-  SDValue ScalarizeVecRes_BUILD_VECTOR(SDNode *N);
+  SDValue ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(SDNode *N);
   SDValue ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N);
   SDValue ScalarizeVecRes_FP_ROUND(SDNode *N);
   SDValue ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(SDNode *N);

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 913aa4536bc81..ee1907b0c67bd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -63,7 +63,10 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
     break;
   case ISD::MERGE_VALUES:      R = ScalarizeVecRes_MERGE_VALUES(N, ResNo);break;
   case ISD::BITCAST:           R = ScalarizeVecRes_BITCAST(N); break;
-  case ISD::BUILD_VECTOR:      R = ScalarizeVecRes_BUILD_VECTOR(N); break;
+  case ISD::SPLAT_VECTOR:
+  case ISD::BUILD_VECTOR:
+    R = ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(N);
+    break;
   case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break;
   case ISD::FP_ROUND:          R = ScalarizeVecRes_FP_ROUND(N); break;
   case ISD::CONVERT_FROM_ARBITRARY_FP:
@@ -475,10 +478,10 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode *N) {
                      NewVT, Op);
 }
 
-SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(SDNode *N) {
+SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(SDNode *N) {
   EVT EltVT = N->getValueType(0).getVectorElementType();
   SDValue InOp = N->getOperand(0);
-  // The BUILD_VECTOR operands may be of wider element types and
+  // The BUILD_VECTOR / SPLAT operands may be of wider element types and
   // we may need to truncate them back to the requested return type.
   if (EltVT.isInteger())
     return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp);

diff  --git a/llvm/test/CodeGen/AArch64/lowmaskedlanes.ll b/llvm/test/CodeGen/AArch64/lowmaskedlanes.ll
index 1a3f88ef11b33..e8de2bdcfb98d 100644
--- a/llvm/test/CodeGen/AArch64/lowmaskedlanes.ll
+++ b/llvm/test/CodeGen/AArch64/lowmaskedlanes.ll
@@ -245,3 +245,14 @@ define void @store_low4_nxv8i16(ptr %p, <vscale x 8 x i16> %a) {
   tail call void @llvm.masked.store(<vscale x 8 x i16> %a, ptr align 1 %p, <vscale x 8 x i1> %m)
   ret void
 }
+
+define void @store_low1_nxv8f16_splat(ptr %0) {
+; CHECK-LABEL: store_low1_nxv8f16_splat:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov h0, #1.00000000
+; CHECK-NEXT:    str h0, [x0]
+; CHECK-NEXT:    ret
+  %2 = tail call <vscale x 8 x i1> @llvm.get.active.lane.mask.nxv8i1.i32(i32 0, i32 1)
+  tail call void @llvm.masked.store.nxv8f16.p0(<vscale x 8 x half> splat (half 0xH3C00), ptr align 2 %0, <vscale x 8 x i1> %2)
+  ret void
+}


        


More information about the llvm-commits mailing list