[llvm] [NFCI][IR] Add optional DataLayout argument to zero and null value related APIs (PR #183208)
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Sat May 2 09:40:34 PDT 2026
================
@@ -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;
----------------
shiltian wrote:
After we change the semantics, this should return false. The challenging part in the future would be in those places where DL is not really available, like the constant folding (not the pass).
https://github.com/llvm/llvm-project/pull/183208
More information about the llvm-commits
mailing list