[clang] 301a6da - AMDGPU: Fix clang side null pointer value for private
Matt Arsenault via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 2 06:39:39 PDT 2020
Author: Matt Arsenault
Date: 2020-06-02T09:23:46-04:00
New Revision: 301a6da8c24a09052e3bda10e90b450b7b39ffea
URL: https://github.com/llvm/llvm-project/commit/301a6da8c24a09052e3bda10e90b450b7b39ffea
DIFF: https://github.com/llvm/llvm-project/commit/301a6da8c24a09052e3bda10e90b450b7b39ffea.diff
LOG: AMDGPU: Fix clang side null pointer value for private
The change to fold_priv_arith looks strange to me, but this was
already the untested behavior for local.
Added:
Modified:
clang/lib/Basic/Targets/AMDGPU.h
clang/test/CodeGenOpenCL/amdgpu-nullptr.cl
Removed:
################################################################################
diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index 6c9060aa3f7b..e4194a881e3f 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -355,7 +355,9 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
// address space has value 0 but in private and local address space has
// value ~0.
uint64_t getNullPointerValue(LangAS AS) const override {
- return AS == LangAS::opencl_local ? ~0 : 0;
+ // FIXME: Also should handle region.
+ return (AS == LangAS::opencl_local || AS == LangAS::opencl_private)
+ ? ~0 : 0;
}
void setAuxTarget(const TargetInfo *Aux) override;
diff --git a/clang/test/CodeGenOpenCL/amdgpu-nullptr.cl b/clang/test/CodeGenOpenCL/amdgpu-nullptr.cl
index ba34d168bf79..753f7f6f4406 100644
--- a/clang/test/CodeGenOpenCL/amdgpu-nullptr.cl
+++ b/clang/test/CodeGenOpenCL/amdgpu-nullptr.cl
@@ -19,7 +19,7 @@ typedef struct {
// Test 0 as initializer.
-// CHECK: @private_p = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
+// CHECK: @private_p = local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
private char *private_p = 0;
// CHECK: @local_p = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
@@ -36,7 +36,7 @@ generic char *generic_p = 0;
// Test NULL as initializer.
-// CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
+// CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
private char *private_p_NULL = NULL;
// CHECK: @local_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
@@ -57,25 +57,28 @@ generic char *generic_p_NULL = NULL;
// CHECK: @fold_generic = local_unnamed_addr addrspace(1) global i32* null, align 8
generic int *fold_generic = (global int*)(generic float*)(private char*)0;
-// CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16 addrspace(5)* null, align 4
+// CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16 addrspace(5)* addrspacecast (i16* null to i16 addrspace(5)*), align 4
private short *fold_priv = (private short*)(generic int*)(global void*)0;
-// CHECK: @fold_priv_arith = local_unnamed_addr addrspace(1) global i8 addrspace(5)* inttoptr (i32 10 to i8 addrspace(5)*), align 4
+// CHECK: @fold_priv_arith = local_unnamed_addr addrspace(1) global i8 addrspace(5)* inttoptr (i32 9 to i8 addrspace(5)*), align 4
private char *fold_priv_arith = (private char*)0 + 10;
-// CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 14, align 4
+// CHECK: @fold_local_arith = local_unnamed_addr addrspace(1) global i8 addrspace(3)* inttoptr (i32 9 to i8 addrspace(3)*), align 4
+local char *fold_local_arith = (local char*)0 + 10;
+
+// CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 13, align 4
int fold_int = (int)(private void*)(generic char*)(global int*)0 + 14;
-// CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 13, align 4
+// CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 12, align 4
int fold_int2 = (int) ((private void*)0 + 13);
-// CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 0, align 4
+// CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 -1, align 4
int fold_int3 = (int) ((private int*)0);
-// CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 8, align 4
+// CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 7, align 4
int fold_int4 = (int) &((private int*)0)[2];
-// CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 4, align 4
+// CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 3, align 4
int fold_int5 = (int) &((private StructTy1*)0)->p2;
@@ -97,12 +100,12 @@ int fold_int5_local = (int) &((local StructTy1*)0)->p2;
// Test static variable initialization.
-// NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8 addrspace(5)* null, align 4
-// NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8 addrspace(5)* null, align 4
-// NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8 addrspace(5)* null, align 4
+// NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
+// NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
+// NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
// NOOPT: @test_static_var_private.sp4 = internal addrspace(1) global i8 addrspace(5)* null, align 4
// NOOPT: @test_static_var_private.sp5 = internal addrspace(1) global i8 addrspace(5)* null, align 4
-// NOOPT: @test_static_var_private.SS1 = internal addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8
+// NOOPT: @test_static_var_private.SS1 = internal addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8
// NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
void test_static_var_private(void) {
@@ -121,7 +124,7 @@ void test_static_var_private(void) {
// NOOPT: @test_static_var_local.sp3 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
// NOOPT: @test_static_var_local.sp4 = internal addrspace(1) global i8 addrspace(3)* null, align 4
// NOOPT: @test_static_var_local.sp5 = internal addrspace(1) global i8 addrspace(3)* null, align 4
-// NOOPT: @test_static_var_local.SS1 = internal addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8
+// NOOPT: @test_static_var_local.SS1 = internal addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8
// NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
void test_static_var_local(void) {
static local char *sp1 = 0;
@@ -136,8 +139,8 @@ void test_static_var_local(void) {
// Test function-scope variable initialization.
// NOOPT-LABEL: @test_func_scope_var_private(
-// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp1, align 4
-// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp2, align 4
+// NOOPT: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* %sp1, align 4
+// NOOPT: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* %sp2, align 4
// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp3, align 4
// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp4, align 4
// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)*
@@ -181,8 +184,8 @@ void test_func_scope_var_local(void) {
// cannot have common linkage since common linkage requires zero initialization
// and does not have explicit section.
-// CHECK: @p1 = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
-// COMMON: @p1 = common local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
+// CHECK: @p1 = local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
+// COMMON: @p1 = weak local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
private char *p1;
// CHECK: @p2 = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
@@ -203,14 +206,14 @@ generic char *p5;
// Test default initialization of structure.
-// CHECK: @S1 = local_unnamed_addr addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8
+// CHECK: @S1 = local_unnamed_addr addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8
StructTy1 S1;
// CHECK: @S2 = local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
StructTy2 S2;
// Test default initialization of array.
-// CHECK: @A1 = local_unnamed_addr addrspace(1) global [2 x %struct.StructTy1] [%struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, %struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }], align 8
+// CHECK: @A1 = local_unnamed_addr addrspace(1) global [2 x %struct.StructTy1] [%struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, %struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }], align 8
StructTy1 A1[2];
// CHECK: @A2 = local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 8
@@ -219,7 +222,7 @@ StructTy2 A2[2];
// Test comparison with 0.
// CHECK-LABEL: cmp_private
-// CHECK: icmp eq i8 addrspace(5)* %p, null
+// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
void cmp_private(private char* p) {
if (p != 0)
*p = 0;
@@ -258,7 +261,7 @@ void cmp_generic(generic char* p) {
// Test comparison with NULL.
// CHECK-LABEL: cmp_NULL_private
-// CHECK: icmp eq i8 addrspace(5)* %p, null
+// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
void cmp_NULL_private(private char* p) {
if (p != NULL)
*p = 0;
@@ -296,7 +299,7 @@ void cmp_NULL_generic(generic char* p) {
// Test storage 0 as null pointer.
// CHECK-LABEL: test_storage_null_pointer
-// CHECK: store i8 addrspace(5)* null, i8 addrspace(5)** %arg_private
+// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)** %arg_private
// CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local
// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global
// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
@@ -315,7 +318,7 @@ void test_storage_null_pointer(private char** arg_private,
// Test storage NULL as null pointer.
// CHECK-LABEL: test_storage_null_pointer_NULL
-// CHECK: store i8 addrspace(5)* null, i8 addrspace(5)** %arg_private
+// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)** %arg_private
// CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local
// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global
// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
@@ -340,8 +343,8 @@ void test_pass_null_pointer_arg_calee(private char* arg_private,
generic char* arg_generic);
// CHECK-LABEL: test_pass_null_pointer_arg
-// CHECK: call void @test_pass_null_pointer_arg_calee(i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(4)* null, i8* null)
-// CHECK: call void @test_pass_null_pointer_arg_calee(i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(4)* null, i8* null)
+// CHECK: call void @test_pass_null_pointer_arg_calee(i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(4)* null, i8* null)
+// CHECK: call void @test_pass_null_pointer_arg_calee(i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(4)* null, i8* null)
void test_pass_null_pointer_arg(void) {
test_pass_null_pointer_arg_calee(0, 0, 0, 0, 0);
test_pass_null_pointer_arg_calee(NULL, NULL, NULL, NULL, NULL);
@@ -355,8 +358,8 @@ void test_cast_null_pointer_to_sizet_calee(size_t arg_private,
size_t arg_generic);
// CHECK-LABEL: test_cast_null_pointer_to_sizet
-// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0)
-// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0)
+// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 ptrtoint (i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*) to i64), i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0) #7
+// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 ptrtoint (i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*) to i64), i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0) #7
void test_cast_null_pointer_to_sizet(void) {
test_cast_null_pointer_to_sizet_calee((size_t)((private char*)0),
(size_t)((local char*)0),
@@ -468,7 +471,7 @@ TEST_EQ00(constant, constant)
// Test cast to bool.
// CHECK-LABEL: cast_bool_private
-// CHECK: icmp eq i8 addrspace(5)* %p, null
+// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
void cast_bool_private(private char* p) {
if (p)
*p = 0;
@@ -513,7 +516,12 @@ typedef struct {
} StructTy3;
// CHECK-LABEL: test_memset_private
-// CHECK: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 {{.*}}, i8 0, i64 40, i1 false)
+// CHECK: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 {{.*}}, i8 0, i64 32, i1 false)
+// CHECK: [[GEP:%.*]] = getelementptr inbounds %struct.StructTy3, %struct.StructTy3 addrspace(5)* %ptr, i32 0, i32 4
+// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* [[GEP]]
+// CHECK: [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(5)* {{.*}}, i32 36
+// CHECK: [[GEP1_CAST:%.*]] = bitcast i8 addrspace(5)* [[GEP1]] to i32 addrspace(5)*
+// CHECK: store i32 0, i32 addrspace(5)* [[GEP1_CAST]], align 4
void test_memset_private(private StructTy3 *ptr) {
StructTy3 S3 = {0, 0, 0, 0, 0};
*ptr = S3;
@@ -529,7 +537,7 @@ local int* test_cast_0_to_local_ptr(void) {
}
// CHECK-LABEL: test_cast_0_to_private_ptr
-// CHECK: ret i32 addrspace(5)* null
+// CHECK: ret i32 addrspace(5)* addrspacecast (i32* null to i32 addrspace(5)*)
private int* test_cast_0_to_private_ptr(void) {
return (private int*)0;
}
@@ -571,7 +579,7 @@ int test_and_nullptr(int a) {
}
// CHECK-LABEL: test_not_private_ptr
-// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(5)* %p, null
+// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
// CHECK: ret i32 %[[lnot_ext]]
int test_not_private_ptr(private char* p) {
@@ -588,7 +596,7 @@ int test_not_local_ptr(local char* p) {
// CHECK-LABEL: test_and_ptr
-// CHECK: %[[tobool:.*]] = icmp ne i8 addrspace(5)* %p1, null
+// CHECK: %[[tobool:.*]] = icmp ne i8 addrspace(5)* %p1, addrspacecast (i8* null to i8 addrspace(5)*)
// CHECK: %[[tobool1:.*]] = icmp ne i8 addrspace(3)* %p2, addrspacecast (i8* null to i8 addrspace(3)*)
// CHECK: %[[res:.*]] = and i1 %[[tobool]], %[[tobool1]]
// CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32
@@ -603,7 +611,7 @@ int test_and_ptr(private char* p1, local char* p2) {
// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
// NOOPT: call void @test_fold_callee
-// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, 0
+// NOOPT: %{{.*}} = add nsw i64 %1, sext (i32 ptrtoint (i32 addrspace(5)* addrspacecast (i32* null to i32 addrspace(5)*) to i32) to i64)
// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
void test_fold_callee(void);
void test_fold_private(void) {
More information about the cfe-commits
mailing list