Skip to content

Commit 76e223c

Browse files
Fznamznonbader
authored andcommitted
[SYCL] Fix address space in casts from derived to base class (#512)
In case of multiple inheritance of non-empty classes clang emits two bitcasts and a GEP for conversion from derived to a base class. First bitcast converts pointer to derived class to int8 pointer, then GEP takes this int8 pointer and applies base class offset, next second bitcast converts int8 pointer with offset to base class pointer. With new SYCL address space rules pointer to derived class may have generic address space. In this case two bitcasts to int8 pointer with generic address space should be emitted. This problem caused assertion fail inside the CodeGen and invalid module generation. Signed-off-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
1 parent 8469578 commit 76e223c

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

Diff for: clang/lib/CodeGen/CGClass.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,9 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr,
246246

247247
// Apply the base offset.
248248
llvm::Value *ptr = addr.getPointer();
249-
ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy);
249+
llvm::Type *resTy = llvm::PointerType::getInt8PtrTy(
250+
CGF.getLLVMContext(), ptr->getType()->getPointerAddressSpace());
251+
ptr = CGF.Builder.CreateBitCast(ptr, resTy);
250252
ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr");
251253

252254
// If we have a virtual component, the alignment of the result will

Diff for: clang/test/CodeGenSYCL/address-space-new.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
// RUN: DISABLE_INFER_AS=1 %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -disable-llvm-passes -emit-llvm -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LEGACY
22
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -disable-llvm-passes -emit-llvm -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NEW
33

4+
struct SpaceWaster {
5+
int i, j;
6+
};
7+
8+
struct HasX {
9+
int x;
10+
};
11+
12+
struct Y : SpaceWaster, HasX {};
13+
14+
void bar(HasX &hx);
15+
16+
void baz(Y &y) {
17+
bar(y);
18+
}
19+
420
void test() {
521
static const int foo = 0x42;
622
// CHECK-LEGACY: @_ZZ4testvE3foo = internal constant i32 66, align 4
@@ -88,6 +104,19 @@ void test() {
88104
(void)select_str_trivial2;
89105
// CHECK-LEGACY: store i8* getelementptr inbounds ([21 x i8], [21 x i8]* @{{.*}}, i64 0, i64 0), i8** %{{.*}}
90106
// CHECK-NEW: store i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([21 x i8], [21 x i8]* @{{.*}}, i64 0, i64 0) to i8 addrspace(4)*), i8 addrspace(4)** %{{.*}}
107+
//
108+
//
109+
Y yy;
110+
baz(yy);
111+
// CHECK: define spir_func void @{{.*}}baz{{.*}}
112+
// CHECK-LEGACY: %[[FIRST:[a-zA-Z0-9]+]] = bitcast %struct.{{.*}}.Y* %{{.*}} to i8*
113+
// CHECK-LEGACY: %[[OFFSET:[a-zA-Z0-9]+]].ptr = getelementptr inbounds i8, i8* %[[FIRST]], i64 8
114+
// CHECK-LEGACY: %[[SECOND:[a-zA-Z0-9]+]] = bitcast i8* %[[OFFSET]].ptr to %struct.{{.*}}.HasX*
115+
// CHECK-LEGACY: call spir_func void @{{.*}}bar{{.*}}(%struct.{{.*}}.HasX* dereferenceable(4) %[[SECOND]])
116+
// CHECK-NEW: %[[FIRST:[a-zA-Z0-9]+]] = bitcast %struct.{{.*}}.Y addrspace(4)* %{{.*}} to i8 addrspace(4)*
117+
// CHECK-NEW: %[[OFFSET:[a-zA-Z0-9]+]].ptr = getelementptr inbounds i8, i8 addrspace(4)* %[[FIRST]], i64 8
118+
// CHECK-NEW: %[[SECOND:[a-zA-Z0-9]+]] = bitcast i8 addrspace(4)* %[[OFFSET]].ptr to %struct.{{.*}}.HasX addrspace(4)*
119+
// CHECK-NEW: call spir_func void @{{.*}}bar{{.*}}(%struct.{{.*}}.HasX addrspace(4)* dereferenceable(4) %[[SECOND]])
91120
}
92121

93122

0 commit comments

Comments
 (0)