[llvm] [RFC][IR] Support vector splats in `ConstantPointerNull` (PR #195486)

via llvm-commits llvm-commits at lists.llvm.org
Sat May 2 15:05:47 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Shilei Tian (shiltian)

<details>
<summary>Changes</summary>

This PR allows `ConstantPointerNull` to represent both scalar pointer nulls and
fixed or scalable vector splats of pointer nulls. This change first aligns with
the native splat behavior of `ConstantInt` and `ConstantFP`, and second, makes
it easier to eventually change the semantics of `ConstantPointerNull` to
represent a semantic null pointer instead of a zero value, which is what it
represents today.


---

Patch is 123.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/195486.diff


56 Files Affected:

- (modified) llvm/include/llvm/IR/Constants.h (+10-7) 
- (modified) llvm/include/llvm/SandboxIR/Constant.h (+2-1) 
- (modified) llvm/lib/Analysis/BasicAliasAnalysis.cpp (+2-2) 
- (modified) llvm/lib/Analysis/GlobalsModRef.cpp (+1-1) 
- (modified) llvm/lib/Analysis/MemoryBuiltins.cpp (+1-1) 
- (modified) llvm/lib/IR/AsmWriter.cpp (+10-1) 
- (modified) llvm/lib/IR/Constants.cpp (+51-4) 
- (modified) llvm/lib/IR/LLVMContextImpl.h (+1-1) 
- (modified) llvm/lib/SandboxIR/Constant.cpp (+6-2) 
- (modified) llvm/lib/Transforms/Utils/ValueMapper.cpp (+1-1) 
- (modified) llvm/test/Assembler/ConstantExprFold.ll (+2-2) 
- (modified) llvm/test/Assembler/aggregate-constant-values.ll (+24) 
- (modified) llvm/test/Assembler/opaque-ptr.ll (+1-1) 
- (modified) llvm/test/CodeGen/AMDGPU/codegen-prepare-addrspacecast-non-null-vector.ll (+1-1) 
- (modified) llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll (+1-1) 
- (modified) llvm/test/CodeGen/AMDGPU/promote-alloca-vector-gep.ll (+7-7) 
- (modified) llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll (+6-6) 
- (modified) llvm/test/Transforms/ConstraintElimination/geps-ptrvector.ll (+1-1) 
- (modified) llvm/test/Transforms/FunctionAttrs/vector-of-pointers-getunderlyingobject-crash.ll (+1-1) 
- (modified) llvm/test/Transforms/InferAddressSpaces/AMDGPU/issue110433.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/call.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/gep-inbounds-null.ll (+3-3) 
- (modified) llvm/test/Transforms/InstCombine/icmp.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/or.ll (+4-4) 
- (modified) llvm/test/Transforms/InstCombine/scalar_vector_gep.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/vscale_cmp.ll (+1-1) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-nonintegral.ll (+4-4) 
- (modified) llvm/test/Transforms/InstSimplify/gep.ll (+7-7) 
- (modified) llvm/test/Transforms/InstSimplify/vscale.ll (+2-2) 
- (modified) llvm/test/Transforms/LoadStoreVectorizer/NVPTX/4x2xhalf.ll (+8-8) 
- (modified) llvm/test/Transforms/LoopIdiom/non-integral-pointers.ll (+2-2) 
- (modified) llvm/test/Transforms/LoopVectorize/X86/cost-model.ll (+2-2) 
- (modified) llvm/test/Transforms/LoopVectorize/X86/interleave-opaque-pointers.ll (+1-1) 
- (modified) llvm/test/Transforms/LoopVectorize/X86/invariant-load-gather.ll (+2-2) 
- (modified) llvm/test/Transforms/LoopVectorize/X86/masked_load_store.ll (+30-30) 
- (modified) llvm/test/Transforms/LoopVectorize/X86/optsize.ll (+2-2) 
- (modified) llvm/test/Transforms/LoopVectorize/find-last.ll (+1-1) 
- (modified) llvm/test/Transforms/LoopVectorize/single_early_exit.ll (+1-1) 
- (modified) llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-outside-iv-users.ll (+8-8) 
- (modified) llvm/test/Transforms/RewriteStatepointsForGC/base-inference.ll (+18-9) 
- (modified) llvm/test/Transforms/RewriteStatepointsForGC/base-pointers.ll (+9-9) 
- (modified) llvm/test/Transforms/RewriteStatepointsForGC/base-vector.ll (+31-31) 
- (modified) llvm/test/Transforms/RewriteStatepointsForGC/insert-extract.ll (+10-10) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/catchswitch-block-in-use.ll (+3-3) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/many-uses-parent-node.ll (+1-1) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/scatter-vectorize-reorder-non-empty.ll (+1-1) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/split-vectorize-phi-user.ll (+1-1) 
- (modified) llvm/test/Transforms/SLPVectorizer/extract-vectorized-operand.ll (+3-3) 
- (modified) llvm/test/Transforms/SLPVectorizer/gep-with-extractelement-many-users.ll (+1-1) 
- (modified) llvm/test/Transforms/SLPVectorizer/revec.ll (+2-2) 
- (modified) llvm/test/Transforms/SROA/vector-promotion.ll (+2-2) 
- (modified) llvm/test/Transforms/Scalarizer/constant-extractelement.ll (+1-1) 
- (modified) llvm/test/Verifier/opaque-ptr.ll (+1-1) 
- (modified) llvm/test/Verifier/ptrmask.ll (+2-2) 
- (modified) llvm/test/tools/llvm-reduce/reduce-operands-ptr.ll (+1-1) 
- (modified) llvm/unittests/IR/ConstantsTest.cpp (+28) 


``````````diff
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index 2b3f4119e50e2..52b1af323f3d3 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -696,12 +696,13 @@ class ConstantVector final : public ConstantAggregate {
 };
 
 //===----------------------------------------------------------------------===//
-/// A constant pointer value that points to null
+/// A constant pointer value that points to null. This represents both scalar
+/// pointer nulls and vector splats of pointer nulls.
 ///
 class ConstantPointerNull final : public ConstantData {
   friend class Constant;
 
-  explicit ConstantPointerNull(PointerType *T)
+  explicit ConstantPointerNull(Type *T)
       : ConstantData(T, Value::ConstantPointerNullVal) {}
 
   void destroyConstantImpl();
@@ -709,13 +710,15 @@ class ConstantPointerNull final : public ConstantData {
 public:
   ConstantPointerNull(const ConstantPointerNull &) = delete;
 
-  /// Static factory methods - Return objects of the specified value
+  /// Static factory methods - Return objects of the specified value. If Ty is a
+  /// vector type, return a ConstantPointerNull with a splat of null pointer
+  /// values. Otherwise return a ConstantPointerNull for the given pointer type.
   LLVM_ABI static ConstantPointerNull *get(PointerType *T);
+  LLVM_ABI static ConstantPointerNull *get(Type *T);
 
-  /// Specialize the getType() method to always return an PointerType,
-  /// which reduces the amount of casting needed in parts of the compiler.
-  inline PointerType *getType() const {
-    return cast<PointerType>(Value::getType());
+  /// Return the scalar pointer type for this null value.
+  inline PointerType *getPointerType() const {
+    return cast<PointerType>(Value::getType()->getScalarType());
   }
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/llvm/include/llvm/SandboxIR/Constant.h b/llvm/include/llvm/SandboxIR/Constant.h
index 669cc79aed957..99543c03de82a 100644
--- a/llvm/include/llvm/SandboxIR/Constant.h
+++ b/llvm/include/llvm/SandboxIR/Constant.h
@@ -773,7 +773,8 @@ class ConstantPointerNull final : public Constant {
 public:
   LLVM_ABI static ConstantPointerNull *get(PointerType *Ty);
 
-  LLVM_ABI PointerType *getType() const;
+  LLVM_ABI Type *getType() const;
+  LLVM_ABI PointerType *getPointerType() const;
 
   /// For isa/dyn_cast.
   static bool classof(const sandboxir::Value *From) {
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index bb8a17c37c881..8172cf29d890b 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1640,10 +1640,10 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
   // Null values in the default address space don't point to any object, so they
   // don't alias any other pointer.
   if (const ConstantPointerNull *CPN = dyn_cast<ConstantPointerNull>(O1))
-    if (!NullPointerIsDefined(&F, CPN->getType()->getAddressSpace()))
+    if (!NullPointerIsDefined(&F, CPN->getPointerType()->getAddressSpace()))
       return AliasResult::NoAlias;
   if (const ConstantPointerNull *CPN = dyn_cast<ConstantPointerNull>(O2))
-    if (!NullPointerIsDefined(&F, CPN->getType()->getAddressSpace()))
+    if (!NullPointerIsDefined(&F, CPN->getPointerType()->getAddressSpace()))
       return AliasResult::NoAlias;
 
   if (O1 != O2) {
diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp
index 295e267848b23..a0d75334f0f2b 100644
--- a/llvm/lib/Analysis/GlobalsModRef.cpp
+++ b/llvm/lib/Analysis/GlobalsModRef.cpp
@@ -773,7 +773,7 @@ bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV,
       if (auto *CPN = dyn_cast<ConstantPointerNull>(Input)) {
         // Null pointer cannot alias with a non-addr-taken global.
         const Function *F = CtxI->getFunction();
-        if (!NullPointerIsDefined(F, CPN->getType()->getAddressSpace()))
+        if (!NullPointerIsDefined(F, CPN->getPointerType()->getAddressSpace()))
           continue;
       }
 
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 0be03eb7af558..a02949548add8 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -1016,7 +1016,7 @@ ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull &CPN) {
   // TODO: How should this work with address space casts? We currently just drop
   // them on the floor, but it's unclear what we should do when a NULL from
   // addrspace(1) gets casted to addrspace(0) (or vice-versa).
-  if (Options.NullIsUnknownSize || CPN.getType()->getAddressSpace())
+  if (Options.NullIsUnknownSize || CPN.getPointerType()->getAddressSpace())
     return ObjectSizeOffsetVisitor::unknown();
   return OffsetSpan(Zero, Zero);
 }
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 29e253e7c5f97..e4bae3ae26011 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1813,7 +1813,16 @@ static void writeConstantInternal(raw_ostream &Out, const Constant *CV,
     return;
   }
 
-  if (isa<ConstantPointerNull>(CV)) {
+  if (const auto *CPN = dyn_cast<ConstantPointerNull>(CV)) {
+    if (CPN->getType()->isVectorTy()) {
+      Out << "splat (";
+      writeAsOperandInternal(Out,
+                             ConstantPointerNull::get(CPN->getPointerType()),
+                             WriterCtx, /*PrintType=*/true);
+      Out << ')';
+      return;
+    }
+
     Out << "null";
     return;
   }
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index f07ce527c1240..795c55e9858cc 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -48,6 +48,22 @@ static cl::opt<bool> UseConstantIntForScalableSplat(
 static cl::opt<bool> UseConstantFPForScalableSplat(
     "use-constant-fp-for-scalable-splat", cl::init(true), cl::Hidden,
     cl::desc("Use ConstantFP's native scalable vector splat support."));
+static cl::opt<bool> UseConstantPtrNullForFixedLengthSplat(
+    "use-constant-ptrnull-for-fixed-length-splat", cl::init(true), cl::Hidden,
+    cl::desc("Use ConstantPointerNull's native fixed-length vector splat "
+             "support."));
+static cl::opt<bool> UseConstantPtrNullForScalableSplat(
+    "use-constant-ptrnull-for-scalable-splat", cl::init(true), cl::Hidden,
+    cl::desc(
+        "Use ConstantPointerNull's native scalable vector splat support."));
+
+static bool shouldUseConstantPointerNullForVector(VectorType *VTy) {
+  if (!VTy->getElementType()->isPointerTy())
+    return false;
+  return VTy->getElementCount().isScalable()
+             ? UseConstantPtrNullForScalableSplat
+             : UseConstantPtrNullForFixedLengthSplat;
+}
 
 //===----------------------------------------------------------------------===//
 //                              Constant Class
@@ -404,10 +420,13 @@ Constant *Constant::getNullValue(Type *Ty) {
                            APFloat::getZero(Ty->getFltSemantics()));
   case Type::PointerTyID:
     return ConstantPointerNull::get(cast<PointerType>(Ty));
-  case Type::StructTyID:
-  case Type::ArrayTyID:
   case Type::FixedVectorTyID:
   case Type::ScalableVectorTyID:
+    if (shouldUseConstantPointerNullForVector(cast<VectorType>(Ty)))
+      return ConstantPointerNull::get(Ty);
+    return ConstantAggregateZero::get(Ty);
+  case Type::StructTyID:
+  case Type::ArrayTyID:
     return ConstantAggregateZero::get(Ty);
   case Type::TokenTyID:
     return ConstantTokenNone::get(Ty->getContext());
@@ -492,6 +511,13 @@ Constant *Constant::getAggregateElement(unsigned Elt) const {
                ? ConstantFP::get(getContext(), CFP->getValue())
                : nullptr;
 
+  if (const auto *CPN = dyn_cast<ConstantPointerNull>(this))
+    return Elt < cast<VectorType>(getType())
+                       ->getElementCount()
+                       .getKnownMinValue()
+               ? ConstantPointerNull::get(CPN->getPointerType())
+               : nullptr;
+
   // FIXME: getNumElements() will fail for non-fixed vector types.
   if (isa<ScalableVectorType>(getType()))
     return nullptr;
@@ -1591,16 +1617,21 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
   bool isSplatFP = UseConstantFPForFixedLengthSplat && isa<ConstantFP>(C);
   bool isSplatInt = UseConstantIntForFixedLengthSplat && isa<ConstantInt>(C);
   bool isSplatByte = isa<ConstantByte>(C);
+  bool isSplatPtrNull =
+      UseConstantPtrNullForFixedLengthSplat && isa<ConstantPointerNull>(C);
 
-  if (isZero || isUndef || isSplatFP || isSplatInt || isSplatByte) {
+  if (isZero || isUndef || isSplatFP || isSplatInt || isSplatByte ||
+      isSplatPtrNull) {
     for (unsigned i = 1, e = V.size(); i != e; ++i)
       if (V[i] != C) {
         isZero = isUndef = isPoison = isSplatFP = isSplatInt = isSplatByte =
-            false;
+            isSplatPtrNull = false;
         break;
       }
   }
 
+  if (isSplatPtrNull)
+    return ConstantPointerNull::get(T);
   if (isZero)
     return ConstantAggregateZero::get(T);
   if (isPoison)
@@ -1628,6 +1659,12 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
 }
 
 Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
+  if (isa<ConstantPointerNull>(V)) {
+    VectorType *VTy = VectorType::get(V->getType(), EC);
+    if (shouldUseConstantPointerNullForVector(VTy))
+      return ConstantPointerNull::get(VTy);
+  }
+
   if (!EC.isScalable()) {
     // Maintain special handling of zero.
     if (!V->isNullValue()) {
@@ -1884,6 +1921,8 @@ Constant *Constant::getSplatValue(bool AllowPoison) const {
     return ConstantByte::get(getContext(), CB->getValue());
   if (auto *CFP = dyn_cast<ConstantFP>(this))
     return ConstantFP::get(getContext(), CFP->getValue());
+  if (auto *CPN = dyn_cast<ConstantPointerNull>(this))
+    return ConstantPointerNull::get(CPN->getPointerType());
   if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
     return CV->getSplatValue();
   if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
@@ -2001,11 +2040,19 @@ ConstantRange Constant::toConstantRange() const {
 //
 
 ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
+  return get(static_cast<Type *>(Ty));
+}
+
+ConstantPointerNull *ConstantPointerNull::get(Type *Ty) {
+  assert((Ty->isPointerTy() ||
+          (Ty->isVectorTy() && Ty->getScalarType()->isPointerTy())) &&
+         "invalid type for null pointer constant");
   std::unique_ptr<ConstantPointerNull> &Entry =
       Ty->getContext().pImpl->CPNConstants[Ty];
   if (!Entry)
     Entry.reset(new ConstantPointerNull(Ty));
 
+  assert(Entry->getType() == Ty);
   return Entry.get();
 }
 
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index ee331f39c4b75..b7645a25989e8 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1697,7 +1697,7 @@ class LLVMContextImpl {
   using VectorConstantsTy = ConstantUniqueMap<ConstantVector>;
   VectorConstantsTy VectorConstants;
 
-  DenseMap<PointerType *, std::unique_ptr<ConstantPointerNull>> CPNConstants;
+  DenseMap<Type *, std::unique_ptr<ConstantPointerNull>> CPNConstants;
 
   DenseMap<TargetExtType *, std::unique_ptr<ConstantTargetNone>> CTNConstants;
 
diff --git a/llvm/lib/SandboxIR/Constant.cpp b/llvm/lib/SandboxIR/Constant.cpp
index 5c50d79d50c8b..4fa01646203ec 100644
--- a/llvm/lib/SandboxIR/Constant.cpp
+++ b/llvm/lib/SandboxIR/Constant.cpp
@@ -225,9 +225,13 @@ ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
   return cast<ConstantPointerNull>(Ty->getContext().getOrCreateConstant(LLVMC));
 }
 
-PointerType *ConstantPointerNull::getType() const {
+Type *ConstantPointerNull::getType() const {
+  return Ctx.getType(cast<llvm::ConstantPointerNull>(Val)->getType());
+}
+
+PointerType *ConstantPointerNull::getPointerType() const {
   return cast<PointerType>(
-      Ctx.getType(cast<llvm::ConstantPointerNull>(Val)->getType()));
+      Ctx.getType(cast<llvm::ConstantPointerNull>(Val)->getPointerType()));
 }
 
 UndefValue *UndefValue::get(Type *T) {
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 73ba1e6a128b0..22230c352bf01 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -539,7 +539,7 @@ Value *Mapper::mapValue(const Value *V) {
   if (isa<ConstantTargetNone>(C))
     return getVM()[V] = Constant::getNullValue(NewTy);
   assert(isa<ConstantPointerNull>(C));
-  return getVM()[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
+  return getVM()[V] = ConstantPointerNull::get(NewTy);
 }
 
 void Mapper::remapDbgRecord(DbgRecord &DR) {
diff --git a/llvm/test/Assembler/ConstantExprFold.ll b/llvm/test/Assembler/ConstantExprFold.ll
index 33ee49296de0a..6945b469889ab 100644
--- a/llvm/test/Assembler/ConstantExprFold.ll
+++ b/llvm/test/Assembler/ConstantExprFold.ll
@@ -37,8 +37,8 @@
 ; CHECK: @cons = weak global i32 0, align 8
 ; CHECK: @gep1 = global <2 x ptr> undef
 ; CHECK: @gep2 = global <2 x ptr> undef
-; CHECK: @gep3 = global <2 x ptr> zeroinitializer
-; CHECK: @gep4 = global <2 x ptr> zeroinitializer
+; CHECK: @gep3 = global <2 x ptr> splat (ptr null)
+; CHECK: @gep4 = global <2 x ptr> splat (ptr null)
 ; CHECK: @bitcast1 = global <2 x i32> splat (i32 -1)
 ; CHECK: @bitcast2 = global <4 x i16> splat (i16 -1)
 ;.
diff --git a/llvm/test/Assembler/aggregate-constant-values.ll b/llvm/test/Assembler/aggregate-constant-values.ll
index b208b582a4657..69a10319083f7 100644
--- a/llvm/test/Assembler/aggregate-constant-values.ll
+++ b/llvm/test/Assembler/aggregate-constant-values.ll
@@ -1,4 +1,5 @@
 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
+; RUN: llvm-as -use-constant-ptrnull-for-fixed-length-splat=false -use-constant-ptrnull-for-scalable-splat=false < %s | llvm-dis -use-constant-ptrnull-for-fixed-length-splat=false -use-constant-ptrnull-for-scalable-splat=false | FileCheck %s --check-prefix=DISABLED
 ; RUN: verify-uselistorder %s
 
 ; CHECK: @foo
@@ -49,3 +50,26 @@ define void @qux_empty(ptr %x) nounwind {
   ret void
 }
 
+; CHECK: @fixed_ptr_null_splat
+; CHECK: ret <2 x ptr> splat (ptr null)
+; DISABLED: @fixed_ptr_null_splat
+; DISABLED: ret <2 x ptr> zeroinitializer
+define <2 x ptr> @fixed_ptr_null_splat() {
+  ret <2 x ptr> zeroinitializer
+}
+
+; CHECK: @scalable_ptr_null_splat
+; CHECK: ret <vscale x 2 x ptr> splat (ptr null)
+; DISABLED: @scalable_ptr_null_splat
+; DISABLED: ret <vscale x 2 x ptr> zeroinitializer
+define <vscale x 2 x ptr> @scalable_ptr_null_splat() {
+  ret <vscale x 2 x ptr> zeroinitializer
+}
+
+; CHECK: @explicit_fixed_ptr_null_splat
+; CHECK: ret <2 x ptr> splat (ptr null)
+; DISABLED: @explicit_fixed_ptr_null_splat
+; DISABLED: ret <2 x ptr> zeroinitializer
+define <2 x ptr> @explicit_fixed_ptr_null_splat() {
+  ret <2 x ptr> splat (ptr null)
+}
diff --git a/llvm/test/Assembler/opaque-ptr.ll b/llvm/test/Assembler/opaque-ptr.ll
index 287b81d2d1c2f..c516f4d11d6ae 100644
--- a/llvm/test/Assembler/opaque-ptr.ll
+++ b/llvm/test/Assembler/opaque-ptr.ll
@@ -92,7 +92,7 @@ define <2 x ptr> @gep_constexpr_vec1(ptr %a) {
 }
 
 ; CHECK: define <2 x ptr> @gep_constexpr_vec2(<2 x ptr> %a)
-; CHECK:     ret <2 x ptr> getelementptr (i16, <2 x ptr> zeroinitializer, <2 x i32> splat (i32 3))
+; CHECK:     ret <2 x ptr> getelementptr (i16, <2 x ptr> splat (ptr null), <2 x i32> splat (i32 3))
 define <2 x ptr> @gep_constexpr_vec2(<2 x ptr> %a) {
   ret <2 x ptr> getelementptr (i16, <2 x ptr> zeroinitializer, i32 3)
 }
diff --git a/llvm/test/CodeGen/AMDGPU/codegen-prepare-addrspacecast-non-null-vector.ll b/llvm/test/CodeGen/AMDGPU/codegen-prepare-addrspacecast-non-null-vector.ll
index 94c571a29f991..d18e1a3004445 100644
--- a/llvm/test/CodeGen/AMDGPU/codegen-prepare-addrspacecast-non-null-vector.ll
+++ b/llvm/test/CodeGen/AMDGPU/codegen-prepare-addrspacecast-non-null-vector.ll
@@ -5,7 +5,7 @@
 
 define <4 x ptr> @vec_of_local_to_flat_nonnull_arg() {
 ; OPT-LABEL: define <4 x ptr> @vec_of_local_to_flat_nonnull_arg() {
-; OPT-NEXT:    [[X:%.*]] = addrspacecast <4 x ptr addrspace(3)> zeroinitializer to <4 x ptr>
+; OPT-NEXT:    [[X:%.*]] = addrspacecast <4 x ptr addrspace(3)> splat (ptr addrspace(3) null) to <4 x ptr>
 ; OPT-NEXT:    ret <4 x ptr> [[X]]
 ;
   %x = addrspacecast <4 x ptr addrspace(3)> zeroinitializer to <4 x ptr>
diff --git a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll
index a09e392b89e63..06064db0d0646 100644
--- a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll
+++ b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll
@@ -209,7 +209,7 @@ define ptr addrspace(7) @inttoptr() {
 define <2 x ptr addrspace(7)> @inttoptr_vec() {
 ; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @inttoptr_vec
 ; CHECK-SAME: () #[[ATTR0]] {
-; CHECK-NEXT:    ret { <2 x ptr addrspace(8)>, <2 x i32> } { <2 x ptr addrspace(8)> zeroinitializer, <2 x i32> <i32 1, i32 2> }
+; CHECK-NEXT:    ret { <2 x ptr addrspace(8)>, <2 x i32> } { <2 x ptr addrspace(8)> splat (ptr addrspace(8) null), <2 x i32> <i32 1, i32 2> }
 ;
   ret <2 x ptr addrspace(7)> inttoptr (<2 x i160> <i160 1, i160 2> to <2 x ptr addrspace(7)>)
 }
diff --git a/llvm/test/CodeGen/AMDGPU/promote-alloca-vector-gep.ll b/llvm/test/CodeGen/AMDGPU/promote-alloca-vector-gep.ll
index fdcbe74dc7ebf..4e9c28071c5af 100644
--- a/llvm/test/CodeGen/AMDGPU/promote-alloca-vector-gep.ll
+++ b/llvm/test/CodeGen/AMDGPU/promote-alloca-vector-gep.ll
@@ -91,7 +91,7 @@ define amdgpu_kernel void @scalar_alloca_ptr_with_vector_gep_offset_select_nullp
 ; CHECK-NEXT:    [[TMP13:%.*]] = add i32 [[TMP12]], [[TMP8]]
 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds [1024 x [4 x i32]], ptr addrspace(3) @scalar_alloca_ptr_with_vector_gep_offset_select_nullptr0.alloca, i32 0, i32 [[TMP13]]
 ; CHECK-NEXT:    [[GETELEMENTPTR0:%.*]] = getelementptr inbounds i8, ptr addrspace(3) [[TMP14]], <4 x i64> <i64 0, i64 1, i64 2, i64 3>
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], <4 x ptr addrspace(3)> zeroinitializer, <4 x ptr addrspace(3)> [[GETELEMENTPTR0]]
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], <4 x ptr addrspace(3)> splat (ptr addrspace(3) null), <4 x ptr addrspace(3)> [[GETELEMENTPTR0]]
 ; CHECK-NEXT:    [[EXTRACTELEMENT:%.*]] = extractelement <4 x ptr addrspace(3)> [[SELECT]], i64 1
 ; CHECK-NEXT:    store i32 0, ptr addrspace(3) [[EXTRACTELEMENT]], align 4
 ; CHECK-NEXT:    ret void
@@ -125,7 +125,7 @@ define amdgpu_kernel void @scalar_alloca_ptr_with_vector_gep_offset_select_nullp
 ; CHECK-NEXT:    [[TMP13:%.*]] = add i32 [[TMP12]], [[TMP8]]
 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds [1024 x [4 x i32]], ptr addrspace(3) @scalar_alloca_ptr_with_vector_gep_offset_select_nullptr1.alloca, i32 0, i32 [[TMP13]]
 ; CHECK-NEXT:    [[GETELEMENTPTR0:%.*]] = getelementptr inbounds i8, ptr addrspace(3) [[TMP14]], <4 x i64> <i64 0, i64 1, i64 2, i64 3>
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], <4 x ptr addrspace(3)> [[GETELEMENTPTR0]], <4 x ptr addrspace(3)> zeroinitializer
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], <4 x ptr addrspace(3)> [[GETELEMENTPTR0]], <4 x ptr addrspace(3)> splat (ptr addrspace(3) null)
 ; CHECK-NEXT:    [[EXTRACTELEMENT:%.*]] = extractelement <4 x ptr addrspace(3)> [[SELECT]], i64 1
 ; CHECK-NEXT:    store i32 0, ptr addrspace(3) [[EXTRACTELEMENT]], align 4
 ; CHECK-NEXT:    ret void
@@ -159,8 +159,8 @@ define amdgpu_kernel void @scalar_alloca_ptr_with_vector_gep_offset_icmp_nullptr
 ; CHECK-NEXT:    [[TMP13:%.*]] = add i32 [[TMP12]], [[TMP8]]
 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds [1024 x [4 x i32]], ptr addrspace(3) @scalar_alloca_ptr_with_vector_gep_offset_icmp_nullptr0.alloca, i32 0, i32 [[TMP13]]
 ; CHECK-NEXT:    [[GETELEMENTPTR0:%.*]] = getelementptr inbounds i8, ptr addrspace(3) [[TMP14]], <4 x i64> <i64 0, i64 1, i64 2, i64 3>
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], <4 x ptr addrspace(3)> zeroinitializer, <4 x ptr addrspace(3)> [[GETELEMENTPTR0]]
-; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq <4 x ptr addrspace(3)> [[SELECT]], zeroinitializer
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], <4 x ptr addrspace(3)> splat (ptr addrspace(3) null), <4 x ptr addrspace(3)> [[GE...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/195486


More information about the llvm-commits mailing list