[llvm] [LLVM][Constants] Return ConstantFP(+0.0) as the NULL value for floating point types. (PR #200465)

Paul Walker via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 12 03:46:10 PDT 2026


https://github.com/paulwalker-arm updated https://github.com/llvm/llvm-project/pull/200465

>From bc34a641d689a6a24016565e9967722359f21096 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Fri, 29 May 2026 10:06:53 +0000
Subject: [PATCH 1/2] [LLVM][Constants] Return ConstantFP(+0.0) as the NULL
 value for floating point types.

---
 llvm/lib/IR/Constants.cpp                        |  8 ++++++--
 llvm/test/CodeGen/ARM/constants.ll               |  5 ++++-
 .../CodeGen/SPIRV/hlsl-intrinsics/discard.ll     |  2 +-
 llvm/test/CodeGen/SPIRV/hlsl-resources/Gather.ll |  5 +++--
 llvm/test/Transforms/InstCombine/frexp.ll        |  3 +--
 .../Reassociate/fast-ReassociateVector.ll        | 16 ++++++++--------
 6 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index cadb48b1a649b..4327ad84874e6 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -378,10 +378,14 @@ Constant *Constant::getNullValue(Type *Ty) {
   case Type::PointerTyID:
     return ConstantPointerNull::get(cast<PointerType>(Ty));
   case Type::FixedVectorTyID:
-  case Type::ScalableVectorTyID:
-    if (cast<VectorType>(Ty)->getElementType()->isPointerTy())
+  case Type::ScalableVectorTyID: {
+    Type *EltTy = cast<VectorType>(Ty)->getElementType();
+    if (EltTy->isFloatingPointTy())
+      return ConstantFP::get(Ty, APFloat::getZero(EltTy->getFltSemantics()));
+    if (EltTy->isPointerTy())
       return ConstantPointerNull::get(Ty);
     return ConstantAggregateZero::get(Ty);
+  }
   case Type::StructTyID:
   case Type::ArrayTyID:
     return ConstantAggregateZero::get(Ty);
diff --git a/llvm/test/CodeGen/ARM/constants.ll b/llvm/test/CodeGen/ARM/constants.ll
index 75a90bbf0caa6..8ab1bdafd1974 100644
--- a/llvm/test/CodeGen/ARM/constants.ll
+++ b/llvm/test/CodeGen/ARM/constants.ll
@@ -62,7 +62,10 @@ define i32 @f8() nounwind {
                                     float 2.000000e+00,
                                     float 3.000000e+00> }, align 16
 ; CHECK: const1
-; CHECK: .zero 16
+; CHECK: .long 0x00000000 @ float 0
+; CHECK: .long 0x00000000 @ float 0
+; CHECK: .long 0x00000000 @ float 0
+; CHECK: .zero 4
 ; CHECK: float 1
 ; CHECK: float 2
 ; CHECK: float 3
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/discard.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/discard.ll
index 60fd1c8a8d170..39be59bbc7332 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/discard.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/discard.ll
@@ -17,7 +17,7 @@
 ; CHECK-DAG:   %[[#v4bool:]]  = OpTypeVector %[[#bool]] 4
 ; CHECK-DAG:   %[[#v4float:]] = OpTypeVector %[[#float]] 4
 ; CHECK-DAG:   %[[#fzero:]] = OpConstant %[[#float]] 0
-; CHECK-DAG:   %[[#v4fzero:]] = OpConstantNull %[[#v4float]]
+; CHECK-DAG:   %[[#v4fzero:]] = OpConstantComposite %[[#v4float]] %[[#fzero]] %[[#fzero]] %[[#fzero]] %[[#fzero]]
 
 define void @test_scalar(float noundef %Buf) {
 entry:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather.ll
index e2e60d7030b76..a2a4781efc2d8 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/Gather.ll
@@ -13,7 +13,8 @@
 ; CHECK-DAG: %[[v2float:[0-9]+]] = OpTypeVector %[[float]] 2
 ; CHECK-DAG: %[[int:[0-9]+]] = OpTypeInt 32 0
 ; CHECK-DAG: %[[v2int:[0-9]+]] = OpTypeVector %[[int]] 2
-; CHECK-DAG: %[[coord:[0-9]+]] = OpConstantNull %[[v2float]]
+; CHECK-DAG: %[[fzero:[0-9]+]] = OpConstant %[[float]] 0
+; CHECK-DAG: %[[coord:[0-9]+]] = OpConstantComposite %[[v2float]] %[[fzero]] %[[fzero]]
 ; CHECK-DAG: %[[component0:[0-9]+]] = OpConstant %[[int]] 0
 ; CHECK-DAG: %[[const1:[0-9]+]] = OpConstant %[[int]] 1
 ; CHECK-DAG: %[[compare:[0-9]+]] = OpConstant %[[float]] 0.5
@@ -21,7 +22,7 @@
 ; CHECK-DAG: %[[image_cube:[0-9]+]] = OpTypeImage %[[float]] Cube 0 0 0 1 Unknown
 ; CHECK-DAG: %[[sampled_image_cube:[0-9]+]] = OpTypeSampledImage %[[image_cube]]
 ; CHECK-DAG: %[[v3float:[0-9]+]] = OpTypeVector %[[float]] 3
-; CHECK-DAG: %[[coord_cube:[0-9]+]] = OpConstantNull %[[v3float]]
+; CHECK-DAG: %[[coord_cube:[0-9]+]] = OpConstantComposite %[[v3float]] %[[fzero]] %[[fzero]] %[[fzero]]
 ; CHECK-DAG: %[[offset_2d:[0-9]+]] = OpConstantNull %[[v2int]]
 ; CHECK-DAG: %[[ptr_int:[0-9]+]] = OpTypePointer Function %[[v2int]]
 
diff --git a/llvm/test/Transforms/InstCombine/frexp.ll b/llvm/test/Transforms/InstCombine/frexp.ll
index 56d2898cae5c6..9f905669a40c8 100644
--- a/llvm/test/Transforms/InstCombine/frexp.ll
+++ b/llvm/test/Transforms/InstCombine/frexp.ll
@@ -109,8 +109,7 @@ define { <2 x float>, <2 x i32> } @frexp_zero_vector() {
 
 define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_zero_scalable_vector() {
 ; CHECK-LABEL: define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_zero_scalable_vector() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> zeroinitializer)
-; CHECK-NEXT:    ret { <vscale x 2 x float>, <vscale x 2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <vscale x 2 x float>, <vscale x 2 x i32> } zeroinitializer
 ;
   %ret = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> zeroinitializer)
   ret { <vscale x 2 x float>, <vscale x 2 x i32> } %ret
diff --git a/llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll b/llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll
index 3e81d581b5ef6..163f5165279a7 100644
--- a/llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll
+++ b/llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll
@@ -476,11 +476,11 @@ define float @test19_scalar(float %x, float %y) {
 
 define <4 x float> @test19_vector(<4 x float> %x, <4 x float> %y) {
 ; CHECK-LABEL: @test19_vector(
-; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <4 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[NEG:%.*]] = fneg reassoc nsz <4 x float> [[Y:%.*]]
+; CHECK-NEXT:    [[X:%.*]] = fadd reassoc nsz <4 x float> [[NEG]], [[X1:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <4 x float> [[X]], zeroinitializer
 ; CHECK-NEXT:    [[TMP2:%.*]] = fadd reassoc nsz <4 x float> [[TMP1]], zeroinitializer
-; CHECK-NEXT:    [[TMP3_NEG:%.*]] = fmul reassoc nsz <4 x float> [[Y:%.*]], splat (float -0.000000e+00)
-; CHECK-NEXT:    [[TMP4:%.*]] = fadd reassoc nsz <4 x float> [[TMP2]], [[TMP3_NEG]]
-; CHECK-NEXT:    ret <4 x float> [[TMP4]]
+; CHECK-NEXT:    ret <4 x float> [[TMP2]]
 ;
   %tmp1 = fmul reassoc nsz <4 x float> %x, zeroinitializer
   %tmp2 = fadd reassoc nsz <4 x float> zeroinitializer, %tmp1
@@ -491,11 +491,11 @@ define <4 x float> @test19_vector(<4 x float> %x, <4 x float> %y) {
 
 define <vscale x 4 x float> @test19_scalable_vector(<vscale x 4 x float> %x, <vscale x 4 x float> %y) {
 ; CHECK-LABEL: @test19_scalable_vector(
-; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <vscale x 4 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[NEG:%.*]] = fneg reassoc nsz <vscale x 4 x float> [[Y:%.*]]
+; CHECK-NEXT:    [[X:%.*]] = fadd reassoc nsz <vscale x 4 x float> [[NEG]], [[X1:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <vscale x 4 x float> [[X]], zeroinitializer
 ; CHECK-NEXT:    [[TMP2:%.*]] = fadd reassoc nsz <vscale x 4 x float> [[TMP1]], zeroinitializer
-; CHECK-NEXT:    [[TMP3_NEG:%.*]] = fmul reassoc nsz <vscale x 4 x float> [[Y:%.*]], splat (float -0.000000e+00)
-; CHECK-NEXT:    [[TMP4:%.*]] = fadd reassoc nsz <vscale x 4 x float> [[TMP2]], [[TMP3_NEG]]
-; CHECK-NEXT:    ret <vscale x 4 x float> [[TMP4]]
+; CHECK-NEXT:    ret <vscale x 4 x float> [[TMP2]]
 ;
   %tmp1 = fmul reassoc nsz <vscale x 4 x float> %x, zeroinitializer
   %tmp2 = fadd reassoc nsz <vscale x 4 x float> zeroinitializer, %tmp1

>From 0c0baf95d5febcf3b0fd55e426da6c326a3dd136 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Fri, 29 May 2026 10:06:53 +0000
Subject: [PATCH 2/2] [LLVM][AsmPrinter] Emit .zero for global ConstantVectors
 containing all zero elements.

This ensures "splat (float 0.0)" and ConstantAggregateZero have
matching behaviour.
---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 10 +++++++---
 llvm/test/CodeGen/ARM/constants.ll         |  5 +----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 17fd80e81a673..cdb9d760606f6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -4163,6 +4163,11 @@ static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP);
 static void emitGlobalConstantVector(const DataLayout &DL, const Constant *CV,
                                      AsmPrinter &AP,
                                      AsmPrinter::AliasMapTy *AliasList) {
+  uint64_t AllocSize = DL.getTypeAllocSize(CV->getType());
+
+  if (CV->isNullValue())
+    return AP.OutStreamer->emitZeros(AllocSize);
+
   auto *VTy = cast<FixedVectorType>(CV->getType());
   Type *ElementType = VTy->getElementType();
   uint64_t ElementSizeInBits = DL.getTypeSizeInBits(ElementType);
@@ -4187,14 +4192,13 @@ static void emitGlobalConstantVector(const DataLayout &DL, const Constant *CV,
     EmittedSize = DL.getTypeStoreSize(CV->getType());
   } else {
     for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
-      emitGlobalAliasInline(AP, DL.getTypeAllocSize(CV->getType()) * I, AliasList);
+      emitGlobalAliasInline(AP, AllocSize * I, AliasList);
       emitGlobalConstantImpl(DL, CV->getAggregateElement(I), AP);
     }
     EmittedSize = DL.getTypeAllocSize(ElementType) * VTy->getNumElements();
   }
 
-  unsigned Size = DL.getTypeAllocSize(CV->getType());
-  if (unsigned Padding = Size - EmittedSize)
+  if (unsigned Padding = AllocSize - EmittedSize)
     AP.OutStreamer->emitZeros(Padding);
 }
 
diff --git a/llvm/test/CodeGen/ARM/constants.ll b/llvm/test/CodeGen/ARM/constants.ll
index 8ab1bdafd1974..75a90bbf0caa6 100644
--- a/llvm/test/CodeGen/ARM/constants.ll
+++ b/llvm/test/CodeGen/ARM/constants.ll
@@ -62,10 +62,7 @@ define i32 @f8() nounwind {
                                     float 2.000000e+00,
                                     float 3.000000e+00> }, align 16
 ; CHECK: const1
-; CHECK: .long 0x00000000 @ float 0
-; CHECK: .long 0x00000000 @ float 0
-; CHECK: .long 0x00000000 @ float 0
-; CHECK: .zero 4
+; CHECK: .zero 16
 ; CHECK: float 1
 ; CHECK: float 2
 ; CHECK: float 3



More information about the llvm-commits mailing list