[RFC][IR] Support vector splats in ConstantPointerNull#195486
Conversation
|
This stack of pull requests is managed by sgh. |
|
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-llvm-analysis Author: Shilei Tian (shiltian) ChangesThis PR allows 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:
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]
|
|
@llvm/pr-subscribers-backend-nvptx Author: Shilei Tian (shiltian) ChangesThis PR allows 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:
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]
|
444848f to
d6ffa06
Compare
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
arichardson
left a comment
There was a problem hiding this comment.
Generally looks good to me just one comment
| 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( |
There was a problem hiding this comment.
Are these options used anywhere? Is this for downstream migration purposes? If so there should be a comment, and if not maybe best to not add any not options that aren't strictly needed.
There was a problem hiding this comment.
I just made it align with the migration of ConstantInt and ConstantFP, where they are guarded by an option. @nikic said they were turned on by default just recently. This is a completely new thing so I don't think there would be any downstream uses at all, but I'm not sure if it is helpful to provide an option to turn it off.
d6ffa06 to
8f81288
Compare
8f81288 to
b07d2a9
Compare
| 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( |
There was a problem hiding this comment.
I don't think this is really necessary, but I guess it's good to be consistent with ConstantInt for now
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.
b07d2a9 to
8c6ee8d
Compare
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/10/builds/27896 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/88/builds/23061 Here is the relevant piece of the build log for the reference |
|
We've started seeing crashes when building chromium that bisect to this commit. I used cvise to but together a minimized reproducer After this commit, running |
|
This PR caused |
This PR allows
ConstantPointerNullto represent both scalar pointer nulls and fixed or scalable vector splats of pointer nulls. This change first aligns with the native splat behavior ofConstantIntandConstantFP, and second, makes it easier to eventually change the semantics ofConstantPointerNullto represent a semantic null pointer instead of a zero value, which is what it represents today.This PR is with help with AI but I reviewed all the code changes.