[llvm-branch-commits] [llvm] [NFCI] Use `DataLayout::getNullPtrValue` in codegen and analysis paths (PR #183210)

Shilei Tian via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Feb 24 15:55:37 PST 2026


https://github.com/shiltian created https://github.com/llvm/llvm-project/pull/183210

Replace hardcoded 0 for null pointer materialization with
`DataLayout::getNullPtrValue(AS)` across codegen, analysis, and
transform paths. This prepares these paths for a future semantic
change where `ConstantPointerNull` may represent a non-zero null
pointer value on certain targets.

NFC because all address spaces currently have all-zero null pointer
values, so `getNullPtrValue` returns 0 for every address space.

>From ca1efd90d731e40a1c7d4b6d5f82fab06fe2bb4d Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at tianshilei.me>
Date: Sun, 15 Feb 2026 00:25:14 -0500
Subject: [PATCH] [NFCI] Use `DataLayout::getNullPtrValue` in codegen and
 analysis paths

Replace hardcoded 0 for null pointer materialization with
`DataLayout::getNullPtrValue(AS)` across codegen, analysis, and
transform paths. This prepares these paths for a future semantic
change where `ConstantPointerNull` may represent a non-zero null
pointer value on certain targets.

NFC because all address spaces currently have all-zero null pointer
values, so `getNullPtrValue` returns 0 for every address space.
---
 llvm/include/llvm/Transforms/Utils/Local.h    |  3 +-
 llvm/lib/Analysis/ValueTracking.cpp           | 10 +++++--
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    | 11 ++++++--
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  |  7 +++--
 .../CodeGen/GlobalISel/MachineIRBuilder.cpp   |  6 ++--
 llvm/lib/CodeGen/SelectionDAG/FastISel.cpp    | 28 +++++++++++--------
 .../lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 15 ++++++----
 .../SelectionDAG/SelectionDAGBuilder.cpp      | 10 +++++--
 llvm/lib/Target/AArch64/AArch64FastISel.cpp   |  8 ++++--
 llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp     | 11 ++++++--
 llvm/lib/Target/X86/X86FastISel.cpp           | 18 ++++++++----
 llvm/lib/Transforms/IPO/SCCP.cpp              |  5 ++--
 llvm/lib/Transforms/Utils/Local.cpp           |  9 ++++--
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp     |  8 ++++--
 llvm/unittests/Transforms/Utils/LocalTest.cpp |  4 +--
 15 files changed, 103 insertions(+), 50 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index 9acfd872e574b..ec89b361fa794 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -514,7 +514,8 @@ LLVM_ABI void hoistAllInstructionsInto(BasicBlock *DomBlock,
 
 /// Given a constant, create a debug information expression.
 LLVM_ABI DIExpression *getExpressionForConstant(DIBuilder &DIB,
-                                                const Constant &C, Type &Ty);
+                                                const Constant &C, Type &Ty,
+                                                const DataLayout &DL);
 
 /// Remap the operands of the debug records attached to \p Inst, and the
 /// operands of \p Inst itself if it's a debug intrinsic.
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c8f53f903428d..5e280eee075aa 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2472,8 +2472,14 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
     Known = KnownBits::makeConstant(*C);
     return;
   }
-  // Null and aggregate-zero are all-zeros.
-  if (isa<ConstantPointerNull>(V) || isa<ConstantAggregateZero>(V)) {
+  // Null pointer: known bits come from the null pointer value for the AS.
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(V)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    Known = KnownBits::makeConstant(Q.DL.getNullPtrValue(AS));
+    return;
+  }
+  // Aggregate-zero is all-zeros.
+  if (isa<ConstantAggregateZero>(V)) {
     Known.setAllZero();
     return;
   }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 083b83567e47f..3225c5b875acf 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -3761,6 +3761,12 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV,
                                         uint64_t Offset) {
   MCContext &Ctx = OutContext;
 
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(CV)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    return MCConstantExpr::create(
+        getDataLayout().getNullPtrValue(AS).getZExtValue(), Ctx);
+  }
+
   if (CV->isNullValue() || isa<UndefValue>(CV))
     return MCConstantExpr::create(0, Ctx);
 
@@ -4396,8 +4402,9 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
       return emitGlobalConstantFP(CFP, AP);
   }
 
-  if (isa<ConstantPointerNull>(CV)) {
-    AP.OutStreamer->emitIntValue(0, Size);
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(CV)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    AP.OutStreamer->emitIntValue(DL.getNullPtrValue(AS).getZExtValue(), Size);
     return;
   }
 
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 56da65cf1ad54..cc0584ef1d63e 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3814,9 +3814,10 @@ bool IRTranslator::translate(const Constant &C, Register Reg) {
     EntryBuilder->buildFConstant(Reg, *CF);
   } else if (isa<UndefValue>(C))
     EntryBuilder->buildUndef(Reg);
-  else if (isa<ConstantPointerNull>(C))
-    EntryBuilder->buildConstant(Reg, 0);
-  else if (auto GV = dyn_cast<GlobalValue>(&C))
+  else if (auto *CPN = dyn_cast<ConstantPointerNull>(&C)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    EntryBuilder->buildConstant(Reg, DL->getNullPtrValue(AS).getZExtValue());
+  } else if (auto GV = dyn_cast<GlobalValue>(&C))
     EntryBuilder->buildGlobalValue(Reg, GV);
   else if (auto CPA = dyn_cast<ConstantPtrAuth>(&C)) {
     Register Addr = getOrCreateVReg(*CPA->getPointer());
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index e379975672c2d..8e4bb5dc35fc9 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -17,6 +17,7 @@
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 
 using namespace llvm;
@@ -117,8 +118,9 @@ MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
       MIB.addImm(CI->getSExtValue());
   } else if (auto *CFP = dyn_cast<ConstantFP>(NumericConstant)) {
     MIB.addFPImm(CFP);
-  } else if (isa<ConstantPointerNull>(NumericConstant)) {
-    MIB.addImm(0);
+  } else if (auto *CPN = dyn_cast<ConstantPointerNull>(NumericConstant)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    MIB.addImm(getDataLayout().getNullPtrValue(AS).getZExtValue());
   } else {
     // Insert $noreg if we didn't find a usable constant and had to drop it.
     MIB.addReg(Register());
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 3247a18bde637..0a4ef90821c06 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -284,12 +284,14 @@ Register FastISel::materializeConstant(const Value *V, MVT VT) {
       Reg = fastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
   } else if (isa<AllocaInst>(V))
     Reg = fastMaterializeAlloca(cast<AllocaInst>(V));
-  else if (isa<ConstantPointerNull>(V))
-    // Translate this as an integer zero so that it can be
-    // local-CSE'd with actual integer zeros.
-    Reg =
-        getRegForValue(Constant::getNullValue(DL.getIntPtrType(V->getType())));
-  else if (const auto *CF = dyn_cast<ConstantFP>(V)) {
+  else if (auto *CPN = dyn_cast<ConstantPointerNull>(V)) {
+    // Translate this as an integer constant so that it can be
+    // local-CSE'd with actual integer constants.
+    unsigned AS = CPN->getType()->getAddressSpace();
+    const APInt &NullVal = DL.getNullPtrValue(AS);
+    Reg = getRegForValue(
+        ConstantInt::get(DL.getIntPtrType(V->getType()), NullVal));
+  } else if (const auto *CF = dyn_cast<ConstantFP>(V)) {
     if (CF->isNullValue())
       Reg = fastMaterializeFloatZero(CF);
     else
@@ -618,9 +620,11 @@ bool FastISel::addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,
     if (const auto *C = dyn_cast<ConstantInt>(Val)) {
       Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp));
       Ops.push_back(MachineOperand::CreateImm(C->getSExtValue()));
-    } else if (isa<ConstantPointerNull>(Val)) {
+    } else if (auto *CPN = dyn_cast<ConstantPointerNull>(Val)) {
+      unsigned AS = CPN->getType()->getAddressSpace();
       Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp));
-      Ops.push_back(MachineOperand::CreateImm(0));
+      Ops.push_back(
+          MachineOperand::CreateImm(DL.getNullPtrValue(AS).getZExtValue()));
     } else if (auto *AI = dyn_cast<AllocaInst>(Val)) {
       // Values coming from a stack location also require a special encoding,
       // but that is added later on by the target specific frame index
@@ -829,9 +833,11 @@ bool FastISel::selectPatchpoint(const CallInst *I) {
       llvm_unreachable("Unsupported ConstantExpr.");
   } else if (const auto *GV = dyn_cast<GlobalValue>(Callee)) {
     Ops.push_back(MachineOperand::CreateGA(GV, 0));
-  } else if (isa<ConstantPointerNull>(Callee))
-    Ops.push_back(MachineOperand::CreateImm(0));
-  else
+  } else if (auto *CPN = dyn_cast<ConstantPointerNull>(Callee)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    Ops.push_back(
+        MachineOperand::CreateImm(DL.getNullPtrValue(AS).getZExtValue()));
+  } else
     llvm_unreachable("Unsupported callee address.");
 
   // Adjust <numArgs> to account for any arguments that have been passed on
diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index a404dcc2660be..ba8e37c7f0e70 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -25,6 +25,7 @@
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/PseudoProbe.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -736,7 +737,8 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
   return EmitDbgValueFromSingleOp(SD, VRBaseMap);
 }
 
-MachineOperand GetMOForConstDbgOp(const SDDbgOperand &Op) {
+MachineOperand GetMOForConstDbgOp(const SDDbgOperand &Op,
+                                  const DataLayout &DL) {
   const Value *V = Op.getConst();
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
     if (CI->getBitWidth() > 64)
@@ -747,9 +749,10 @@ MachineOperand GetMOForConstDbgOp(const SDDbgOperand &Op) {
   }
   if (const ConstantFP *CF = dyn_cast<ConstantFP>(V))
     return MachineOperand::CreateFPImm(CF);
-  // Note: This assumes that all nullptr constants are zero-valued.
-  if (isa<ConstantPointerNull>(V))
-    return MachineOperand::CreateImm(0);
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(V)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    return MachineOperand::CreateImm(DL.getNullPtrValue(AS).getZExtValue());
+  }
   // Undef or unhandled value type, so return an undef operand.
   return MachineOperand::CreateReg(
       /* Reg */ 0U, /* isDef */ false, /* isImp */ false,
@@ -784,7 +787,7 @@ void InstrEmitter::AddDbgValueLocationOps(
                    /*IsDebug=*/true, /*IsClone=*/false, /*IsCloned=*/false);
     } break;
     case SDDbgOperand::CONST:
-      MIB.add(GetMOForConstDbgOp(Op));
+      MIB.add(GetMOForConstDbgOp(Op, MF->getDataLayout()));
       break;
     }
   }
@@ -886,7 +889,7 @@ InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD,
       DefMI = &*MRI->def_instr_begin(VReg);
     } else {
       assert(DbgOperand.getKind() == SDDbgOperand::CONST);
-      MOs.push_back(GetMOForConstDbgOp(DbgOperand));
+      MOs.push_back(GetMOForConstDbgOp(DbgOperand, MF->getDataLayout()));
       continue;
     }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index e21bfa8498c88..0462970d03d12 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1875,8 +1875,11 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
                          getValue(CPA->getDiscriminator()));
     }
 
-    if (isa<ConstantPointerNull>(C))
-      return DAG.getConstant(0, getCurSDLoc(), VT);
+    if (auto *CPN = dyn_cast<ConstantPointerNull>(C)) {
+      unsigned AS = CPN->getType()->getAddressSpace();
+      const APInt &NullVal = DAG.getDataLayout().getNullPtrValue(AS);
+      return DAG.getConstant(NullVal, getCurSDLoc(), VT);
+    }
 
     if (match(C, m_VScale()))
       return DAG.getVScale(getCurSDLoc(), VT, APInt(VT.getSizeInBits(), 1));
@@ -3628,7 +3631,8 @@ void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
                            TLI.getPointerTy(DAG.getDataLayout())),
         dl, ValueVTs[0]);
   } else {
-    Ops[0] = DAG.getConstant(0, dl, TLI.getPointerTy(DAG.getDataLayout()));
+    Ops[0] = DAG.getConstant(DAG.getDataLayout().getNullPtrValue(0), dl,
+                             TLI.getPointerTy(DAG.getDataLayout()));
   }
   Ops[1] = DAG.getZExtOrTrunc(
       DAG.getCopyFromReg(DAG.getEntryNode(), dl,
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index 8c0377fa5550f..fcf8a4f948fbd 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -537,9 +537,13 @@ Register AArch64FastISel::fastMaterializeConstant(const Constant *C) {
   MVT VT = CEVT.getSimpleVT();
   // arm64_32 has 32-bit pointers held in 64-bit registers. Because of that,
   // 'null' pointers need to have a somewhat special treatment.
-  if (isa<ConstantPointerNull>(C)) {
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(C)) {
     assert(VT == MVT::i64 && "Expected 64-bit pointers");
-    return materializeInt(ConstantInt::get(Type::getInt64Ty(*Context), 0), VT);
+    unsigned AS = CPN->getType()->getAddressSpace();
+    return materializeInt(
+        ConstantInt::get(Type::getInt64Ty(*Context),
+                         DL.getNullPtrValue(AS).getZExtValue()),
+        VT);
   }
 
   if (const auto *CI = dyn_cast<ConstantInt>(C))
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index b18d6239f0026..3b45e8eb9a441 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -1573,8 +1573,9 @@ void NVPTXAsmPrinter::printScalarConstant(const Constant *CPV, raw_ostream &O) {
     printFPConstant(CFP, O);
     return;
   }
-  if (isa<ConstantPointerNull>(CPV)) {
-    O << "0";
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(CPV)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    O << getDataLayout().getNullPtrValue(AS);
     return;
   }
   if (const GlobalValue *GVar = dyn_cast<GlobalValue>(CPV)) {
@@ -1746,6 +1747,12 @@ NVPTXAsmPrinter::lowerConstantForGV(const Constant *CV,
                                     bool ProcessingGeneric) const {
   MCContext &Ctx = OutContext;
 
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(CV)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    return MCConstantExpr::create(
+        getDataLayout().getNullPtrValue(AS).getZExtValue(), Ctx);
+  }
+
   if (CV->isNullValue() || isa<UndefValue>(CV))
     return MCConstantExpr::create(0, Ctx);
 
diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp
index bd36f2ccf4aed..167f51d47fbd5 100644
--- a/llvm/lib/Target/X86/X86FastISel.cpp
+++ b/llvm/lib/Target/X86/X86FastISel.cpp
@@ -654,9 +654,12 @@ bool X86FastISel::X86FastEmitStore(EVT VT, Register ValReg, X86AddressMode &AM,
 bool X86FastISel::X86FastEmitStore(EVT VT, const Value *Val,
                                    X86AddressMode &AM,
                                    MachineMemOperand *MMO, bool Aligned) {
-  // Handle 'null' like i32/i64 0.
-  if (isa<ConstantPointerNull>(Val))
-    Val = Constant::getNullValue(DL.getIntPtrType(Val->getContext()));
+  // Handle 'null' like i32/i64 null pointer value.
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(Val)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    Val = ConstantInt::get(DL.getIntPtrType(Val->getContext()),
+                           DL.getNullPtrValue(AS));
+  }
 
   // If this is a store of a simple constant, fold the constant into the store.
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
@@ -1405,9 +1408,12 @@ bool X86FastISel::X86FastEmitCompare(const Value *Op0, const Value *Op1, EVT VT,
   if (!Op0Reg)
     return false;
 
-  // Handle 'null' like i32/i64 0.
-  if (isa<ConstantPointerNull>(Op1))
-    Op1 = Constant::getNullValue(DL.getIntPtrType(Op0->getContext()));
+  // Handle 'null' like i32/i64 null pointer value.
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(Op1)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    Op1 = ConstantInt::get(DL.getIntPtrType(Op0->getContext()),
+                           DL.getNullPtrValue(AS));
+  }
 
   // We have two options: compare with register or immediate.  If the RHS of
   // the compare is an immediate that we can fold into this compare, use
diff --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp
index 2ecadd529170f..0221e6a21c670 100644
--- a/llvm/lib/Transforms/IPO/SCCP.cpp
+++ b/llvm/lib/Transforms/IPO/SCCP.cpp
@@ -350,8 +350,9 @@ static bool runIPSCCP(
     GV->getDebugInfo(GVEs);
     if (GVEs.size() == 1) {
       DIBuilder DIB(M);
-      if (DIExpression *InitExpr = getExpressionForConstant(
-              DIB, *GV->getInitializer(), *GV->getValueType()))
+      if (DIExpression *InitExpr =
+              getExpressionForConstant(DIB, *GV->getInitializer(),
+                                       *GV->getValueType(), M.getDataLayout()))
         GVEs[0]->replaceOperandWith(1, InitExpr);
     }
 
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index bd617cd003a76..c9e8ce0611193 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3442,7 +3442,7 @@ void llvm::hoistAllInstructionsInto(BasicBlock *DomBlock, Instruction *InsertPt,
 }
 
 DIExpression *llvm::getExpressionForConstant(DIBuilder &DIB, const Constant &C,
-                                             Type &Ty) {
+                                             Type &Ty, const DataLayout &DL) {
   // Create integer constant expression.
   auto createIntegerExpression = [&DIB](const Constant &CV) -> DIExpression * {
     const APInt &API = cast<ConstantInt>(&CV)->getValue();
@@ -3471,8 +3471,11 @@ DIExpression *llvm::getExpressionForConstant(DIBuilder &DIB, const Constant &C,
   if (!Ty.isPointerTy())
     return nullptr;
 
-  if (isa<ConstantPointerNull>(C))
-    return DIB.createConstantValueExpression(0);
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(&C)) {
+    unsigned AS = CPN->getType()->getAddressSpace();
+    return DIB.createConstantValueExpression(
+        DL.getNullPtrValue(AS).getZExtValue());
+  }
 
   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(&C))
     if (CE->getOpcode() == Instruction::IntToPtr) {
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index fd9aff0f9fef2..95cc209721352 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -545,9 +545,11 @@ static ConstantInt *getConstantInt(Value *V, const DataLayout &DL) {
   // ConstantInt if possible.
   IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(V->getType()));
 
-  // Null pointer means 0, see SelectionDAGBuilder::getValue(const Value*).
-  if (isa<ConstantPointerNull>(V))
-    return ConstantInt::get(IntPtrTy, 0);
+  // Null pointer value comes from DataLayout.
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(V)) {
+    return cast<ConstantInt>(ConstantInt::get(
+        IntPtrTy, DL.getNullPtrValue(CPN->getType()->getAddressSpace())));
+  }
 
   // IntToPtr const int, we can look through this if the semantics of
   // inttoptr for this address space are a simple (truncating) bitcast.
diff --git a/llvm/unittests/Transforms/Utils/LocalTest.cpp b/llvm/unittests/Transforms/Utils/LocalTest.cpp
index 896e1de8b32f3..86cf72c2599cd 100644
--- a/llvm/unittests/Transforms/Utils/LocalTest.cpp
+++ b/llvm/unittests/Transforms/Utils/LocalTest.cpp
@@ -1138,8 +1138,8 @@ TEST(Local, ExpressionForConstant) {
         Ty, false, GlobalValue::ExternalLinkage, C, "GV");
     EXPECT_NE(GV, nullptr);
 
-    DIExpression *Expr = getExpressionForConstant(DIB, *GV->getInitializer(),
-                                                  *GV->getValueType());
+    DIExpression *Expr = getExpressionForConstant(
+        DIB, *GV->getInitializer(), *GV->getValueType(), M.getDataLayout());
     if (Expr) {
       EXPECT_EQ(Expr->getNumElements(), 3u);
       EXPECT_EQ(Expr->getElement(0), dwarf::DW_OP_constu);



More information about the llvm-branch-commits mailing list