Skip to content

Commit 0f7903f

Browse files
committed
[SYCL] Fix address space in casts from derived to base class
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 <[email protected]>
1 parent 0e44dd2 commit 0f7903f

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

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

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)