From 0f7903f9cac646ec2e537e8e1b5282d0f7abbea4 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Wed, 14 Aug 2019 17:07:54 +0300 Subject: [PATCH 1/2] [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 --- clang/lib/CodeGen/CGClass.cpp | 4 ++- clang/test/CodeGenSYCL/address-space-new.cpp | 29 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index b08f367361ff1..5f25d3b761756 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -246,7 +246,9 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, // Apply the base offset. llvm::Value *ptr = addr.getPointer(); - ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy); + llvm::Type *ResTy = llvm::PointerType::getInt8PtrTy( + CGF.getLLVMContext(), ptr->getType()->getPointerAddressSpace()); + ptr = CGF.Builder.CreateBitCast(ptr, ResTy); ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr"); // If we have a virtual component, the alignment of the result will diff --git a/clang/test/CodeGenSYCL/address-space-new.cpp b/clang/test/CodeGenSYCL/address-space-new.cpp index d01eb1e54cfe1..d4cda4bdf7575 100644 --- a/clang/test/CodeGenSYCL/address-space-new.cpp +++ b/clang/test/CodeGenSYCL/address-space-new.cpp @@ -1,6 +1,22 @@ // 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 // 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 +struct SpaceWaster { + int i, j; +}; + +struct HasX { + int x; +}; + +struct Y : SpaceWaster, HasX {}; + +void bar(HasX &hx); + +void baz(Y &y) { + bar(y); +} + void test() { static const int foo = 0x42; // CHECK-LEGACY: @_ZZ4testvE3foo = internal constant i32 66, align 4 @@ -88,6 +104,19 @@ void test() { (void)select_str_trivial2; // CHECK-LEGACY: store i8* getelementptr inbounds ([21 x i8], [21 x i8]* @{{.*}}, i64 0, i64 0), i8** %{{.*}} // 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)** %{{.*}} + // + // + Y yy; + baz(yy); + // CHECK: define spir_func void @{{.*}}baz{{.*}} + // CHECK-LEGACY: %[[FIRST:[a-zA-Z0-9]+]] = bitcast %struct.{{.*}}.Y* %{{.*}} to i8* + // CHECK-LEGACY: %[[OFFSET:[a-zA-Z0-9]+]].ptr = getelementptr inbounds i8, i8* %[[FIRST]], i64 8 + // CHECK-LEGACY: %[[SECOND:[a-zA-Z0-9]+]] = bitcast i8* %[[OFFSET]].ptr to %struct.{{.*}}.HasX* + // CHECK-LEGACY: call spir_func void @{{.*}}bar{{.*}}(%struct.{{.*}}.HasX* dereferenceable(4) %[[SECOND]]) + // CHECK-NEW: %[[FIRST:[a-zA-Z0-9]+]] = bitcast %struct.{{.*}}.Y addrspace(4)* %{{.*}} to i8 addrspace(4)* + // CHECK-NEW: %[[OFFSET:[a-zA-Z0-9]+]].ptr = getelementptr inbounds i8, i8 addrspace(4)* %[[FIRST]], i64 8 + // CHECK-NEW: %[[SECOND:[a-zA-Z0-9]+]] = bitcast i8 addrspace(4)* %[[OFFSET]].ptr to %struct.{{.*}}.HasX addrspace(4)* + // CHECK-NEW: call spir_func void @{{.*}}bar{{.*}}(%struct.{{.*}}.HasX addrspace(4)* dereferenceable(4) %[[SECOND]]) } From afb9089f78014a3db7d5279f1d71665a68a6216c Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Fri, 16 Aug 2019 13:59:06 +0300 Subject: [PATCH 2/2] Apply reviewer's comment Signed-off-by: Mariya Podchishchaeva --- clang/lib/CodeGen/CGClass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 5f25d3b761756..38720fdb9084a 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -246,9 +246,9 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, // Apply the base offset. llvm::Value *ptr = addr.getPointer(); - llvm::Type *ResTy = llvm::PointerType::getInt8PtrTy( + llvm::Type *resTy = llvm::PointerType::getInt8PtrTy( CGF.getLLVMContext(), ptr->getType()->getPointerAddressSpace()); - ptr = CGF.Builder.CreateBitCast(ptr, ResTy); + ptr = CGF.Builder.CreateBitCast(ptr, resTy); ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr"); // If we have a virtual component, the alignment of the result will