[llvm] [LLVM][CodeGen][SPIRV] Match NULL splat to OpConstantNull. (PR #201313)

Paul Walker via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 3 03:47:18 PDT 2026


https://github.com/paulwalker-arm created https://github.com/llvm/llvm-project/pull/201313

I'm hoping the transformation stands on its own, but the rational for the change is https://github.com/llvm/llvm-project/pull/200465, where I'm changing the canonical form of NULL floating point vectors.

>From 7e97ee547113a07ce20feede49c74ee989cdb68a Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Tue, 2 Jun 2026 14:47:43 +0000
Subject: [PATCH] [LLVM][CodeGen][SPIRV] Match NULL splat to OpConstantNull.

I'm hoping the transformation stands on its own, but the rational for
the change is https://github.com/llvm/llvm-project/pull/200465, where
I'm changing the canonical form of NULL floating point vectors.
---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp    | 16 ++++++++++++++++
 llvm/test/CodeGen/SPIRV/FCmpFalse_Vec.ll         |  5 ++---
 .../CodeGen/SPIRV/llvm-intrinsics/is_fpclass.ll  |  2 +-
 .../signed_arithmetic_overflow.ll                |  2 +-
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index c3f21fe025bd5..e39b514a36e2f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3921,6 +3921,22 @@ bool SPIRVInstructionSelector::selectBuildVector(Register ResVReg,
         I, "There must be at least two constituent operands in a vector");
 
   MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
+
+  bool IsNullVector = IsConst;
+  for (unsigned i = I.getNumExplicitDefs();
+       i < I.getNumExplicitOperands() && IsNullVector; ++i) {
+    MachineInstr *Def = getDef(I.getOperand(i), MRI);
+    IsNullVector = Def && isNullOrNullSplat(*Def, *MRI);
+  }
+
+  if (IsNullVector) {
+    BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
+        .addDef(ResVReg)
+        .addUse(GR.getSPIRVTypeID(ResType))
+        .constrainAllUses(TII, TRI, RBI);
+    return true;
+  }
+
   auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
                      TII.get(IsConst ? SPIRV::OpConstantComposite
                                      : SPIRV::OpCompositeConstruct))
diff --git a/llvm/test/CodeGen/SPIRV/FCmpFalse_Vec.ll b/llvm/test/CodeGen/SPIRV/FCmpFalse_Vec.ll
index c410b64c6997a..e73fad581d7c5 100644
--- a/llvm/test/CodeGen/SPIRV/FCmpFalse_Vec.ll
+++ b/llvm/test/CodeGen/SPIRV/FCmpFalse_Vec.ll
@@ -3,9 +3,8 @@
 
 ; CHECK: %[[#BoolTy:]] = OpTypeBool
 ; CHECK: %[[#VecTy:]] = OpTypeVector %[[#BoolTy]] 4
-; CHECK: %[[#False:]] = OpConstantFalse %[[#BoolTy]]
-; CHECK: %[[#Composite:]] = OpConstantComposite %[[#VecTy]] %[[#False]] %[[#False]] %[[#False]] %[[#False]]
-; CHECK: OpReturnValue %[[#Composite]]
+; CHECK: %[[#NullVec:]] = OpConstantNull %[[#VecTy]]
+; CHECK: OpReturnValue %[[#NullVec]]
 
 define spir_func <4 x i1> @test(<4 x float> %a) {
  %compare = fcmp false <4 x float> %a, %a
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/is_fpclass.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/is_fpclass.ll
index ec8330c16c8fd..41a143cf655d6 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/is_fpclass.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/is_fpclass.ll
@@ -33,7 +33,7 @@
 ; CHECK-DAG: %[[#InfFP64:]] = OpConstant %[[#I64Ty]] 9218868437227405312
 ; CHECK-DAG: %[[#NegInfFP64:]] = OpConstant %[[#I64Ty]] 18442240474082181120
 
-; CHECK-DAG: %[[#FalseV4:]] = OpConstantComposite %[[#V4BoolTy]] %[[#False]] %[[#False]] %[[#False]] %[[#False]]
+; CHECK-DAG: %[[#FalseV4:]] = OpConstantNull %[[#V4BoolTy]]
 ; CHECK-DAG: %[[#ValueMaskV4:]] = OpConstantComposite %[[#V4I32Ty]] %[[#ValueMask]] %[[#ValueMask]] %[[#ValueMask]] %[[#ValueMask]]
 ; CHECK-DAG: %[[#InfV4:]] = OpConstantComposite %[[#V4I32Ty]] %[[#Inf]] %[[#Inf]] %[[#Inf]] %[[#Inf]]
 ; CHECK-DAG: %[[#InfWithQnanBitV4:]] = OpConstantComposite %[[#V4I32Ty]] %[[#InfWithQnanBit]] %[[#InfWithQnanBit]] %[[#InfWithQnanBit]] %[[#InfWithQnanBit]]
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/signed_arithmetic_overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/signed_arithmetic_overflow.ll
index ae721ba6ce269..5827c563f3253 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/signed_arithmetic_overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/signed_arithmetic_overflow.ll
@@ -8,7 +8,7 @@
 ; CHECK-DAG: %[[#NullInt:]] = OpConstantNull %[[#Int]]
 ; CHECK-DAG: %[[#V2Int:]] = OpTypeVector %[[#Int]] 2
 ; CHECK-DAG: %[[#V2Bool:]] = OpTypeVector %[[#Bool]] 2
-; CHECK-DAG: %[[#NullV2Int:]] = OpConstantComposite %[[#V2Int]]
+; CHECK-DAG: %[[#NullV2Int:]] = OpConstantNull %[[#V2Int]]
 
 ; CHECK: OpFunction
 ; CHECK: %[[#A:]] = OpFunctionParameter %[[#Int]]



More information about the llvm-commits mailing list