Skip to content

Commit c62baaf

Browse files
committed
[WIP][IR][Constants] Change the semantic of ConstantPointerNull to represent an actual nullptr instead of a zero-value pointer
The value of a `nullptr` is not always `0`. For example, on AMDGPU, the `nullptr` in address spaces 3 and 5 is `0xffffffff`. Currently, there is no target-independent way to get this information, making it difficult and error-prone to handle null pointers in target-agnostic code. We do have `ConstantPointerNull`, but it might be a little confusing and misleading. It represents a pointer with an all-zero value rather than necessarily a real `nullptr`. Therefore, to represent a real `nullptr` in address space `N`, we need to use `addrspacecast ptr null to ptr addrspace(N)` and it can't be folded. In this PR, we change the semantic of `ConstantPointerNull` to represent an actual `nullptr` instead of a zero-value pointer. Here is the detailed changes. * `ptr addrspace(N) null` will represent the actual `nullptr` in address space `N`. * `ptr addrspace(N) zeroinitializer` will represent a zero-value pointer in address space `N`. * `Constant::getNullValue` will return a _null_ value. It is same as the current semantics except for the `PointerType`, which will return a real `nullptr` pointer. * `Constant::getZeroValue` will return a zero value constant. It is completely same as the current semantics. To represent a zero-value pointer, a `ConstantExpr` will be used (effectively `inttoptr i8 0 to ptr addrspace(N)`). * Correspondingly, there will be both `Constant::isNullValue` and `Constant::isZeroValue`. The RFC is https://discourse.llvm.org/t/rfc-introduce-sentinel-pointer-value-to-datalayout/85265. It is a little bit old and the title might look different, but everything eventually converges to this change. An early attempt can be found in #131557, which has many valuable discussion as well. This PR is still WIP but any early feedback is welcome. I'll include as many necessary code changes as possible in this PR, but eventually this needs to be carefully split into multiple PRs, and I'll do it after the changes look good to every one.
1 parent ca7edf2 commit c62baaf

File tree

110 files changed

+1229
-918
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+1229
-918
lines changed

clang/lib/Basic/Targets/AMDGPU.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static const char *const DataLayoutStringR600 =
3131
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1";
3232

3333
static const char *const DataLayoutStringAMDGCN =
34-
"e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
34+
"e-m:e-p:64:64-p1:64:64-po2:32:32-po3:32:32-p4:64:64-po5:32:32-p6:32:32"
3535
"-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-"
3636
"v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-"
3737
"v2048:2048-n32:64-S32-A5-G1-ni:7:8:9";

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,8 +1218,9 @@ void CodeGenFunction::emitStoresForConstant(const VarDecl &D, Address Loc,
12181218
if (IsAutoInit)
12191219
I->addAnnotationMetadata("auto-init");
12201220

1221-
bool valueAlreadyCorrect =
1222-
constant->isNullValue() || isa<llvm::UndefValue>(constant);
1221+
bool valueAlreadyCorrect = constant->isNullValue() ||
1222+
constant->isZeroValue() ||
1223+
isa<llvm::UndefValue>(constant);
12231224
if (!valueAlreadyCorrect) {
12241225
Loc = Loc.withElementType(Ty);
12251226
emitStoresForInitAfterBZero(constant, Loc, isVolatile, IsAutoInit);

clang/test/CodeGen/target-data.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,12 @@
160160

161161
// RUN: %clang_cc1 -triple amdgcn-unknown -target-cpu hawaii -o - -emit-llvm %s \
162162
// RUN: | FileCheck %s -check-prefix=R600SI
163-
// R600SI: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
163+
// R600SI: target datalayout = "e-m:e-p:64:64-p1:64:64-po2:32:32-po3:32:32-p4:64:64-po5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
164164

165165
// Test default -target-cpu
166166
// RUN: %clang_cc1 -triple amdgcn-unknown -o - -emit-llvm %s \
167167
// RUN: | FileCheck %s -check-prefix=R600SIDefault
168-
// R600SIDefault: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
168+
// R600SIDefault: target datalayout = "e-m:e-p:64:64-p1:64:64-po2:32:32-po3:32:32-p4:64:64-po5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
169169

170170
// RUN: %clang_cc1 -triple arm64-unknown -o - -emit-llvm %s | \
171171
// RUN: FileCheck %s -check-prefix=AARCH64
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 %s -O0 -triple amdgcn -emit-llvm -o - | FileCheck %s
22
// RUN: %clang_cc1 %s -O0 -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s
33

4-
// CHECK: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
4+
// CHECK: target datalayout = "e-m:e-p:64:64-p1:64:64-po2:32:32-po3:32:32-p4:64:64-po5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
55
void foo(void) {}

lld/test/ELF/lto/amdgcn-oses.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
;--- amdhsa.ll
2727
target triple = "amdgcn-amd-amdhsa"
28-
target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
28+
target datalayout = "e-m:e-p:64:64-p1:64:64-po2:32:32-po3:32:32-p4:64:64-po5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
2929

3030
!llvm.module.flags = !{!0}
3131
!0 = !{i32 1, !"amdhsa_code_object_version", i32 500}
@@ -36,15 +36,15 @@ define void @_start() {
3636

3737
;--- amdpal.ll
3838
target triple = "amdgcn-amd-amdpal"
39-
target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
39+
target datalayout = "e-m:e-p:64:64-p1:64:64-po2:32:32-po3:32:32-p4:64:64-po5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
4040

4141
define amdgpu_cs void @_start() {
4242
ret void
4343
}
4444

4545
;--- mesa3d.ll
4646
target triple = "amdgcn-amd-mesa3d"
47-
target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
47+
target datalayout = "e-m:e-p:64:64-p1:64:64-po2:32:32-po3:32:32-p4:64:64-po5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
4848

4949
define void @_start() {
5050
ret void

lld/test/ELF/lto/amdgcn.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
; Make sure the amdgcn triple is handled
66

77
target triple = "amdgcn-amd-amdhsa"
8-
target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
8+
target datalayout = "e-m:e-p:64:64-p1:64:64-po2:32:32-po3:32:32-p4:64:64-po5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
99

1010
define void @_start() {
1111
ret void

llvm/docs/LangRef.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3349,8 +3349,12 @@ as follows:
33493349
default address space 0. The value of ``<as>`` must be in the range [1,2^24).
33503350
The optional ``<flags>`` are used to specify properties of pointers in this
33513351
address space: the character ``u`` marks pointers as having an unstable
3352-
representation, and ``e`` marks pointers having external state. See
3353-
:ref:`Non-Integral Pointer Types <nointptrtype>`.
3352+
representation; ``e`` marks pointers having external state; ``z`` marks the
3353+
value of the nullptr as all-zeros (default behavior if it is not specified);
3354+
``o`` marks the value of the nullptr as all-ones; ``c`` marks the value of
3355+
the nullptr as custom (neither all-zeros nor all-ones), such that LLVM will
3356+
not be able to fold various casts involving nullptr.
3357+
See :ref:`Non-Integral Pointer Types <nointptrtype>`.
33543358

33553359
``i<size>:<abi>[:<pref>]``
33563360
This specifies the alignment for an integer type of a given bit

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ enum ConstantsCodes {
439439
CST_CODE_PTRAUTH = 33, // [ptr, key, disc, addrdisc]
440440
CST_CODE_PTRAUTH2 = 34, // [ptr, key, disc, addrdisc,
441441
// deactivation_symbol]
442+
CST_CODE_ZERO_VALUE = 35, // ZERO_VALUE
442443
};
443444

444445
/// CastOpcodes - These are values used in the bitcode files to encode which

llvm/include/llvm/IR/Constant.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ class Constant : public User {
192192

193193
LLVM_ABI static Constant *getNullValue(Type *Ty);
194194

195+
LLVM_ABI static Constant *getZeroValue(Type *Ty);
196+
195197
/// @returns the value for an integer or vector of integer constant of the
196198
/// given type that has all its bits set to true.
197199
/// Get the all ones value

llvm/include/llvm/IR/Constants.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,9 @@ class ConstantAggregate : public Constant {
414414
/// Transparently provide more efficient getOperand methods.
415415
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
416416

417+
/// Return true if the constant aggregate contains all null values.
418+
inline bool isNullValue() const;
419+
417420
/// Methods for support type inquiry through isa, cast, and dyn_cast:
418421
static bool classof(const Value *V) {
419422
return V->getValueID() >= ConstantAggregateFirstVal &&
@@ -443,6 +446,8 @@ class ConstantArray final : public ConstantAggregate {
443446
// ConstantArray accessors
444447
LLVM_ABI static Constant *get(ArrayType *T, ArrayRef<Constant *> V);
445448

449+
LLVM_ABI static Constant *getNullValue(ArrayType *T);
450+
446451
private:
447452
static Constant *getImpl(ArrayType *T, ArrayRef<Constant *> V);
448453

@@ -475,6 +480,8 @@ class ConstantStruct final : public ConstantAggregate {
475480
// ConstantStruct accessors
476481
LLVM_ABI static Constant *get(StructType *T, ArrayRef<Constant *> V);
477482

483+
LLVM_ABI static Constant *getNullValue(StructType *T);
484+
478485
template <typename... Csts>
479486
static std::enable_if_t<are_base_of<Constant, Csts...>::value, Constant *>
480487
get(StructType *T, Csts *...Vs) {
@@ -527,6 +534,8 @@ class ConstantVector final : public ConstantAggregate {
527534
// ConstantVector accessors
528535
LLVM_ABI static Constant *get(ArrayRef<Constant *> V);
529536

537+
LLVM_ABI static Constant *getNullValue(VectorType *T);
538+
530539
private:
531540
static Constant *getImpl(ArrayRef<Constant *> V);
532541

0 commit comments

Comments
 (0)