[llvm] [NFCI][IR] Add DataLayout pointer to zero and null value related APIs (PR #183208)

Shilei Tian via llvm-commits llvm-commits at lists.llvm.org
Sat May 2 09:28:30 PDT 2026


https://github.com/shiltian updated https://github.com/llvm/llvm-project/pull/183208

>From d1a9dfea4c351cb754148b82e4158154f6a90e90 Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at tianshilei.me>
Date: Sat, 2 May 2026 10:58:40 -0400
Subject: [PATCH] [NFCI][IR] Add DataLayout pointer to zero and null value
 related APIs

When the semantics of `ConstantPointerNull` change to represent a semantic null
pointer in the future, a null value won't necessarily be a zero value anymore.
Because of that, the entire LLVM constant infrastructure will need to change. As
a first step, this PR adds an optional data layout pointer to `isNullValue`,
`isZeroValue`, `getNullValue`, and `getZeroValue`. It isn't used yet, since a
null value is still a zero value right now.
---
 llvm/include/llvm/IR/Constant.h     |  22 ++-
 llvm/lib/IR/Constants.cpp           | 137 +++++++++++++++--
 llvm/unittests/IR/ConstantsTest.cpp | 227 ++++++++++++++++++++++++++++
 3 files changed, 373 insertions(+), 13 deletions(-)

diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h
index 82a570e8a1446..cef1292444012 100644
--- a/llvm/include/llvm/IR/Constant.h
+++ b/llvm/include/llvm/IR/Constant.h
@@ -22,6 +22,7 @@ namespace llvm {
 
 class ConstantRange;
 class APInt;
+class DataLayout;
 
 /// This is an important base class in LLVM. It provides the common facilities
 /// of all constant values in an LLVM program. A constant is a value that is
@@ -52,7 +53,10 @@ class Constant : public User {
   Constant(const Constant &) = delete;
 
   /// Return true if this is the value that would be returned by getNullValue.
-  LLVM_ABI bool isNullValue() const;
+  LLVM_ABI bool isNullValue(const DataLayout *DL = nullptr) const;
+
+  /// Return true iff this constant has an all-zero bit pattern.
+  LLVM_ABI bool isZeroValue(const DataLayout *DL = nullptr) const;
 
   /// Returns true if the value is one.
   LLVM_ABI bool isOneValue() const;
@@ -187,7 +191,21 @@ class Constant : public User {
   ///
   LLVM_ABI void handleOperandChange(Value *, Value *);
 
-  LLVM_ABI static Constant *getNullValue(Type *Ty);
+  /// Constructor to create a null constant of arbitrary type.
+  /// TODO: Currently equivalent to getZeroValue(). Will diverge once the
+  /// semantics of ConstantPointerNull changes: for pointer types in address
+  /// spaces with non-zero null, getNullValue() will return the semantic null
+  /// pointer (ConstantPointerNull) while getZeroValue() will continue to return
+  /// the all-zero-bits value.
+  LLVM_ABI static Constant *getNullValue(Type *Ty,
+                                         const DataLayout *DL = nullptr);
+
+  /// Return the all-zero-bits constant for the given type.
+  /// TODO: For pointer types, it returns ConstantPointerNull but this will
+  /// change once the semantics of ConstantPointerNull changes to represent the
+  /// semantic null pointer.
+  LLVM_ABI static Constant *getZeroValue(Type *Ty,
+                                         const DataLayout *DL = nullptr);
 
   /// @returns the value for an integer or vector of integer constant of the
   /// given type that has all its bits set to true.
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index f07ce527c1240..cb61d7695bebe 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -17,6 +17,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/ConstantFold.h"
+#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GetElementPtrTypeIterator.h"
@@ -71,25 +72,134 @@ bool Constant::isNegativeZeroValue() const {
   return isNullValue();
 }
 
-bool Constant::isNullValue() const {
-  // 0 is null.
+// ConstantAggregateZero is always zero value. Whether it is also the null value
+// depends on whether the zero value is null value for each element type.
+static bool isZeroAggregateNullValue(Type *Ty, const DataLayout *DL) {
+  if (StructType *STy = dyn_cast<StructType>(Ty)) {
+    for (Type *EltTy : STy->elements()) {
+      if (!Constant::getZeroValue(EltTy, DL)->isNullValue(DL))
+        return false;
+    }
+    return true;
+  }
+
+  if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+    if (ATy->getNumElements() == 0)
+      return true;
+    return Constant::getZeroValue(ATy->getElementType(), DL)->isNullValue(DL);
+  }
+
+  VectorType *VTy = cast<VectorType>(Ty);
+  return Constant::getZeroValue(VTy->getElementType(), DL)->isNullValue(DL);
+}
+
+bool Constant::isNullValue(const DataLayout *DL) const {
+  if (isa<UndefValue>(this))
+    return false;
+
+  if (isa<ConstantPointerNull>(this))
+    return true;
+
+  if (isa<ConstantAggregateZero>(this))
+    return isZeroAggregateNullValue(getType(), DL);
+
+  if (StructType *STy = dyn_cast<StructType>(getType())) {
+    for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
+      Constant *Elt = getAggregateElement(I);
+      if (!Elt || !Elt->isNullValue(DL))
+        return false;
+    }
+    return true;
+  }
+
+  if (ArrayType *ATy = dyn_cast<ArrayType>(getType())) {
+    for (uint64_t I = 0, E = ATy->getNumElements(); I != E; ++I) {
+      Constant *Elt = getAggregateElement(I);
+      if (!Elt || !Elt->isNullValue(DL))
+        return false;
+    }
+    return true;
+  }
+
+  if (FixedVectorType *VTy = dyn_cast<FixedVectorType>(getType())) {
+    for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
+      Constant *Elt = getAggregateElement(I);
+      if (!Elt || !Elt->isNullValue(DL))
+        return false;
+    }
+    return true;
+  }
+
+  if (isa<ScalableVectorType>(getType())) {
+    if (Constant *Splat = getSplatValue())
+      return Splat->isNullValue(DL);
+  }
+
+  return isZeroValue(DL);
+}
+
+bool Constant::isZeroValue(const DataLayout *DL) const {
+  if (isa<UndefValue>(this))
+    return false;
+
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
     return CI->isZero();
 
-  // 0 is null.
   if (const ConstantByte *CB = dyn_cast<ConstantByte>(this))
     return CB->isZero();
 
-  // +0.0 is null.
-  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
+  // +0.0 is zero but -0.0 is not.
+  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) {
     // ppc_fp128 determine isZero using high order double only
     // Should check the bitwise value to make sure all bits are zero.
     return CFP->isExactlyValue(+0.0);
+  }
+
+  if (isa<ConstantAggregateZero>(this) || isa<ConstantTokenNone>(this) ||
+      isa<ConstantTargetNone>(this))
+    return true;
+
+  if (const ConstantPointerNull *CPN = dyn_cast<ConstantPointerNull>(this)) {
+    // FIXME: This should return false once the semantics of ConstantPointerNull
+    // changes.
+    if (!DL)
+      return true;
+    return DL->getNullPtrValue(CPN->getType()->getAddressSpace()).isZero();
+  }
+
+  if (StructType *STy = dyn_cast<StructType>(getType())) {
+    for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
+      Constant *Elt = getAggregateElement(I);
+      if (!Elt || !Elt->isZeroValue(DL))
+        return false;
+    }
+    return true;
+  }
 
-  // constant zero is zero for aggregates, cpnull is null for pointers, none for
-  // tokens.
-  return isa<ConstantAggregateZero>(this) || isa<ConstantPointerNull>(this) ||
-         isa<ConstantTokenNone>(this) || isa<ConstantTargetNone>(this);
+  if (ArrayType *ATy = dyn_cast<ArrayType>(getType())) {
+    for (uint64_t I = 0, E = ATy->getNumElements(); I != E; ++I) {
+      Constant *Elt = getAggregateElement(I);
+      if (!Elt || !Elt->isZeroValue(DL))
+        return false;
+    }
+    return true;
+  }
+
+  if (FixedVectorType *VTy = dyn_cast<FixedVectorType>(getType())) {
+    for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
+      Constant *Elt = getAggregateElement(I);
+      if (!Elt || !Elt->isZeroValue(DL))
+        return false;
+    }
+    return true;
+  }
+
+  if (isa<ScalableVectorType>(getType())) {
+    if (Constant *Splat = getSplatValue())
+      return Splat->isZeroValue(DL);
+  }
+
+  return false;
 }
 
 bool Constant::isAllOnesValue() const {
@@ -386,8 +496,13 @@ bool Constant::containsConstantExpression() const {
   return false;
 }
 
-/// Constructor to create a '0' constant of arbitrary type.
-Constant *Constant::getNullValue(Type *Ty) {
+Constant *Constant::getNullValue(Type *Ty, const DataLayout *DL) {
+  // TODO: when the semantics of ConstantPointerNull changes, a null value is
+  // not necessarily a zero value.
+  return getZeroValue(Ty, DL);
+}
+
+Constant *Constant::getZeroValue(Type *Ty, const DataLayout *DL) {
   switch (Ty->getTypeID()) {
   case Type::ByteTyID:
     return ConstantByte::get(Ty, 0);
diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp
index 34898aa467788..71a8646e98055 100644
--- a/llvm/unittests/IR/ConstantsTest.cpp
+++ b/llvm/unittests/IR/ConstantsTest.cpp
@@ -10,6 +10,7 @@
 #include "llvm-c/Core.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/ConstantFold.h"
+#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instruction.h"
@@ -868,5 +869,231 @@ TEST(ConstantsTest, Float128Test) {
   LLVMContextDispose(C);
 }
 
+TEST(ConstantsTest, ZeroValueAPIs) {
+  LLVMContext Context;
+
+  Type *Int32Ty = Type::getInt32Ty(Context);
+  Type *FloatTy = Type::getFloatTy(Context);
+  Type *DoubleTy = Type::getDoubleTy(Context);
+  Type *PtrTy = PointerType::get(Context, /*AddressSpace=*/0);
+  Type *Ptr1Ty = PointerType::get(Context, /*AddressSpace=*/1);
+  Type *PtrVecTy = FixedVectorType::get(PtrTy, /*NumElts=*/2);
+  Type *Ptr1VecTy = FixedVectorType::get(Ptr1Ty, /*NumElts=*/2);
+  ArrayType *PtrArrayTy = ArrayType::get(PtrTy, /*NumElements=*/2);
+  ArrayType *Ptr1ArrayTy = ArrayType::get(Ptr1Ty, /*NumElements=*/2);
+  ArrayType *EmptyPtrArrayTy = ArrayType::get(PtrTy, /*NumElements=*/0);
+  StructType *StructTy = StructType::get(Int32Ty, PtrTy);
+  StructType *StructWithAS1PtrTy = StructType::get(Int32Ty, Ptr1Ty);
+  StructType *EmptyStructTy = StructType::get(Context);
+  ArrayType *ArrayTy = ArrayType::get(Int32Ty, /*NumElements=*/4);
+
+  Constant *IntZero = ConstantInt::get(Int32Ty, 0);
+  Constant *IntOne = ConstantInt::get(Int32Ty, 1);
+  Constant *FPZero = ConstantFP::get(FloatTy, 0.0);
+  Constant *FPNegZero = ConstantFP::get(FloatTy, -0.0);
+  Constant *FPOne = ConstantFP::get(FloatTy, 1.0);
+  Constant *PtrNull0 = ConstantPointerNull::get(cast<PointerType>(PtrTy));
+  Constant *PtrNull1 = ConstantPointerNull::get(cast<PointerType>(Ptr1Ty));
+  Constant *PtrVecZero = ConstantAggregateZero::get(PtrVecTy);
+  Constant *Ptr1VecZero = ConstantAggregateZero::get(Ptr1VecTy);
+  Constant *PtrArrayZero = ConstantAggregateZero::get(PtrArrayTy);
+  Constant *Ptr1ArrayZero = ConstantAggregateZero::get(Ptr1ArrayTy);
+  Constant *CAZ = ConstantAggregateZero::get(StructTy);
+  Constant *StructWithAS1PtrZero =
+      ConstantAggregateZero::get(StructWithAS1PtrTy);
+  Constant *EmptyArrayUndef = UndefValue::get(EmptyPtrArrayTy);
+  Constant *EmptyArrayPoison = PoisonValue::get(EmptyPtrArrayTy);
+  Constant *EmptyStructUndef = UndefValue::get(EmptyStructTy);
+  Constant *EmptyStructPoison = PoisonValue::get(EmptyStructTy);
+
+  // TODO: Null and zero are still the same value. The DataLayout argument is
+  // accepted by the API but is not used yet.
+  EXPECT_EQ(Constant::getZeroValue(Int32Ty), Constant::getNullValue(Int32Ty));
+  EXPECT_EQ(Constant::getZeroValue(FloatTy), Constant::getNullValue(FloatTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrTy), Constant::getNullValue(PtrTy));
+  EXPECT_EQ(Constant::getZeroValue(Ptr1Ty), Constant::getNullValue(Ptr1Ty));
+  EXPECT_EQ(Constant::getZeroValue(PtrVecTy), Constant::getNullValue(PtrVecTy));
+  EXPECT_EQ(Constant::getZeroValue(Ptr1VecTy),
+            Constant::getNullValue(Ptr1VecTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrArrayTy),
+            Constant::getNullValue(PtrArrayTy));
+  EXPECT_EQ(Constant::getZeroValue(Ptr1ArrayTy),
+            Constant::getNullValue(Ptr1ArrayTy));
+  EXPECT_EQ(Constant::getZeroValue(StructTy), Constant::getNullValue(StructTy));
+  EXPECT_EQ(Constant::getZeroValue(StructWithAS1PtrTy),
+            Constant::getNullValue(StructWithAS1PtrTy));
+  EXPECT_EQ(Constant::getZeroValue(ArrayTy), Constant::getNullValue(ArrayTy));
+
+  EXPECT_TRUE(IntZero->isZeroValue());
+  EXPECT_FALSE(IntOne->isZeroValue());
+  EXPECT_TRUE(FPZero->isZeroValue());
+  // -0.0 has a non-zero bit pattern (sign bit set), so it is NOT a zero value.
+  EXPECT_FALSE(FPNegZero->isZeroValue());
+  EXPECT_FALSE(FPOne->isZeroValue());
+  EXPECT_TRUE(PtrNull0->isZeroValue());
+  EXPECT_TRUE(PtrNull1->isZeroValue());
+  EXPECT_TRUE(PtrVecZero->isZeroValue());
+  EXPECT_TRUE(Ptr1VecZero->isZeroValue());
+  EXPECT_TRUE(PtrArrayZero->isZeroValue());
+  EXPECT_TRUE(Ptr1ArrayZero->isZeroValue());
+  EXPECT_TRUE(CAZ->isZeroValue());
+  EXPECT_TRUE(StructWithAS1PtrZero->isZeroValue());
+  EXPECT_FALSE(EmptyArrayUndef->isZeroValue());
+  EXPECT_FALSE(EmptyArrayPoison->isZeroValue());
+  EXPECT_FALSE(EmptyStructUndef->isZeroValue());
+  EXPECT_FALSE(EmptyStructPoison->isZeroValue());
+  EXPECT_FALSE(EmptyArrayUndef->isNullValue());
+  EXPECT_FALSE(EmptyArrayPoison->isNullValue());
+  EXPECT_FALSE(EmptyStructUndef->isNullValue());
+  EXPECT_FALSE(EmptyStructPoison->isNullValue());
+
+  // -0.0 is NOT zero (sign bit set = non-zero bit pattern).
+  // Verify consistency with isNullValue: both agree +0.0 is zero, -0.0 is not.
+  EXPECT_TRUE(FPZero->isNullValue());
+  EXPECT_FALSE(FPNegZero->isNullValue());
+  EXPECT_TRUE(FPZero->isZeroValue());
+  EXPECT_FALSE(FPNegZero->isZeroValue());
+
+  Constant *DblZero = ConstantFP::get(DoubleTy, 0.0);
+  Constant *DblNegZero = ConstantFP::get(DoubleTy, -0.0);
+  EXPECT_TRUE(DblZero->isZeroValue());
+  EXPECT_FALSE(DblNegZero->isZeroValue());
+
+  // Vector splats of FP zeros.
+  Constant *VecPosZero =
+      ConstantVector::getSplat(ElementCount::getFixed(2), FPZero);
+  Constant *VecNegZero =
+      ConstantVector::getSplat(ElementCount::getFixed(2), FPNegZero);
+  // Splat of +0.0 collapses to CAZ, which is zero.
+  EXPECT_TRUE(isa<ConstantAggregateZero>(VecPosZero));
+  EXPECT_TRUE(VecPosZero->isZeroValue());
+  // Splat of -0.0 does NOT collapse to CAZ and is NOT zero.
+  EXPECT_FALSE(isa<ConstantAggregateZero>(VecNegZero));
+  EXPECT_FALSE(VecNegZero->isZeroValue());
+
+  DataLayout DefaultDL("");
+  DataLayout AllOnesDL("po1:64:64");
+
+  EXPECT_TRUE(IntZero->isZeroValue(&DefaultDL));
+  EXPECT_FALSE(IntOne->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(FPZero->isZeroValue(&DefaultDL));
+  EXPECT_FALSE(FPNegZero->isZeroValue(&DefaultDL));
+  EXPECT_FALSE(FPOne->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(PtrNull0->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(PtrNull1->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(PtrVecZero->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(Ptr1VecZero->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(PtrArrayZero->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(Ptr1ArrayZero->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(CAZ->isZeroValue(&DefaultDL));
+  EXPECT_TRUE(StructWithAS1PtrZero->isZeroValue(&DefaultDL));
+  EXPECT_FALSE(EmptyArrayUndef->isZeroValue(&DefaultDL));
+  EXPECT_FALSE(EmptyArrayPoison->isZeroValue(&DefaultDL));
+  EXPECT_FALSE(EmptyStructUndef->isZeroValue(&DefaultDL));
+  EXPECT_FALSE(EmptyStructPoison->isZeroValue(&DefaultDL));
+  EXPECT_FALSE(EmptyArrayUndef->isNullValue(&DefaultDL));
+  EXPECT_FALSE(EmptyArrayPoison->isNullValue(&DefaultDL));
+  EXPECT_FALSE(EmptyStructUndef->isNullValue(&DefaultDL));
+  EXPECT_FALSE(EmptyStructPoison->isNullValue(&DefaultDL));
+
+  // AS 1 has an all-ones null pointer representation in this layout, so
+  // ConstantPointerNull is null but not zero there.
+  EXPECT_TRUE(PtrNull0->isZeroValue(&AllOnesDL));
+  EXPECT_FALSE(PtrNull1->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(PtrNull0->isNullValue(&AllOnesDL));
+  EXPECT_TRUE(PtrNull1->isNullValue(&AllOnesDL));
+  EXPECT_TRUE(PtrVecZero->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(Ptr1VecZero->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(PtrVecZero->isNullValue(&AllOnesDL));
+  EXPECT_TRUE(Ptr1VecZero->isNullValue(&AllOnesDL));
+  EXPECT_TRUE(PtrArrayZero->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(Ptr1ArrayZero->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(PtrArrayZero->isNullValue(&AllOnesDL));
+  EXPECT_TRUE(Ptr1ArrayZero->isNullValue(&AllOnesDL));
+  EXPECT_TRUE(IntZero->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(FPZero->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(CAZ->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(StructWithAS1PtrZero->isZeroValue(&AllOnesDL));
+  EXPECT_TRUE(StructWithAS1PtrZero->isNullValue(&AllOnesDL));
+
+  EXPECT_EQ(Constant::getNullValue(Int32Ty, /*DL=*/nullptr),
+            Constant::getNullValue(Int32Ty));
+  EXPECT_EQ(Constant::getZeroValue(Int32Ty, /*DL=*/nullptr),
+            Constant::getZeroValue(Int32Ty));
+  EXPECT_EQ(Constant::getNullValue(PtrTy, /*DL=*/nullptr),
+            Constant::getNullValue(PtrTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrTy, /*DL=*/nullptr),
+            Constant::getZeroValue(PtrTy));
+  EXPECT_EQ(Constant::getNullValue(StructTy, /*DL=*/nullptr),
+            Constant::getNullValue(StructTy));
+  EXPECT_EQ(Constant::getZeroValue(StructTy, /*DL=*/nullptr),
+            Constant::getZeroValue(StructTy));
+
+  EXPECT_EQ(Constant::getNullValue(Int32Ty, &DefaultDL),
+            Constant::getNullValue(Int32Ty));
+  EXPECT_EQ(Constant::getZeroValue(Int32Ty, &DefaultDL),
+            Constant::getZeroValue(Int32Ty));
+  EXPECT_EQ(Constant::getNullValue(PtrTy, &DefaultDL),
+            Constant::getNullValue(PtrTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrTy, &DefaultDL),
+            Constant::getZeroValue(PtrTy));
+  EXPECT_EQ(Constant::getNullValue(PtrVecTy, &DefaultDL),
+            Constant::getNullValue(PtrVecTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrVecTy, &DefaultDL),
+            Constant::getZeroValue(PtrVecTy));
+  EXPECT_EQ(Constant::getNullValue(PtrArrayTy, &DefaultDL),
+            Constant::getNullValue(PtrArrayTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrArrayTy, &DefaultDL),
+            Constant::getZeroValue(PtrArrayTy));
+  EXPECT_EQ(Constant::getNullValue(StructTy, &DefaultDL),
+            Constant::getNullValue(StructTy));
+  EXPECT_EQ(Constant::getZeroValue(StructTy, &DefaultDL),
+            Constant::getZeroValue(StructTy));
+  EXPECT_EQ(Constant::getNullValue(ArrayTy, &DefaultDL),
+            Constant::getNullValue(ArrayTy));
+  EXPECT_EQ(Constant::getZeroValue(ArrayTy, &DefaultDL),
+            Constant::getZeroValue(ArrayTy));
+
+  // TODO: The DataLayout argument does not affect getNullValue() or
+  // getZeroValue() yet, even for pointer-containing types in an address space
+  // with a non-zero null pointer value.
+  EXPECT_EQ(Constant::getNullValue(Int32Ty, &AllOnesDL),
+            Constant::getNullValue(Int32Ty));
+  EXPECT_EQ(Constant::getZeroValue(Int32Ty, &AllOnesDL),
+            Constant::getZeroValue(Int32Ty));
+  EXPECT_EQ(Constant::getNullValue(PtrTy, &AllOnesDL),
+            Constant::getNullValue(PtrTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrTy, &AllOnesDL),
+            Constant::getZeroValue(PtrTy));
+  EXPECT_EQ(Constant::getNullValue(Ptr1Ty, &AllOnesDL),
+            Constant::getNullValue(Ptr1Ty));
+  EXPECT_EQ(Constant::getZeroValue(Ptr1Ty, &AllOnesDL),
+            Constant::getZeroValue(Ptr1Ty));
+  EXPECT_EQ(Constant::getNullValue(PtrVecTy, &AllOnesDL),
+            Constant::getNullValue(PtrVecTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrVecTy, &AllOnesDL),
+            Constant::getZeroValue(PtrVecTy));
+  EXPECT_EQ(Constant::getNullValue(Ptr1VecTy, &AllOnesDL),
+            Constant::getNullValue(Ptr1VecTy));
+  EXPECT_EQ(Constant::getZeroValue(Ptr1VecTy, &AllOnesDL),
+            Constant::getZeroValue(Ptr1VecTy));
+  EXPECT_EQ(Constant::getNullValue(PtrArrayTy, &AllOnesDL),
+            Constant::getNullValue(PtrArrayTy));
+  EXPECT_EQ(Constant::getZeroValue(PtrArrayTy, &AllOnesDL),
+            Constant::getZeroValue(PtrArrayTy));
+  EXPECT_EQ(Constant::getNullValue(Ptr1ArrayTy, &AllOnesDL),
+            Constant::getNullValue(Ptr1ArrayTy));
+  EXPECT_EQ(Constant::getZeroValue(Ptr1ArrayTy, &AllOnesDL),
+            Constant::getZeroValue(Ptr1ArrayTy));
+  EXPECT_EQ(Constant::getNullValue(StructTy, &AllOnesDL),
+            Constant::getNullValue(StructTy));
+  EXPECT_EQ(Constant::getZeroValue(StructTy, &AllOnesDL),
+            Constant::getZeroValue(StructTy));
+  EXPECT_EQ(Constant::getNullValue(StructWithAS1PtrTy, &AllOnesDL),
+            Constant::getNullValue(StructWithAS1PtrTy));
+  EXPECT_EQ(Constant::getZeroValue(StructWithAS1PtrTy, &AllOnesDL),
+            Constant::getZeroValue(StructWithAS1PtrTy));
+}
+
 } // end anonymous namespace
 } // end namespace llvm



More information about the llvm-commits mailing list