[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