Skip to content

Commit 81d6a89

Browse files
Fznamznonbader
authored andcommitted
[SYCL] Fix address space of return values
Emit address space cast if return type and return value have different address spaces. Signed-off-by: Mariya Podchishchaeva <[email protected]>
1 parent 6d7f2d3 commit 81d6a89

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,12 +1090,40 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
10901090
// If this function returns a reference, take the address of the expression
10911091
// rather than the value.
10921092
RValue Result = EmitReferenceBindingToExpr(RV);
1093-
Builder.CreateStore(Result.getScalarVal(), ReturnValue);
1093+
llvm::Value *Val = Result.getScalarVal();
1094+
if (!getenv("DISABLE_INFER_AS")) {
1095+
if (auto *PtrTy = dyn_cast<llvm::PointerType>(Val->getType())) {
1096+
auto *ExpectedPtrType =
1097+
cast<llvm::PointerType>(ReturnValue.getType()->getElementType());
1098+
unsigned ValueAS = PtrTy->getAddressSpace();
1099+
unsigned ExpectedAS = ExpectedPtrType->getAddressSpace();
1100+
if (ValueAS != ExpectedAS) {
1101+
Val =
1102+
Builder.CreatePointerBitCastOrAddrSpaceCast(Val, ExpectedPtrType);
1103+
}
1104+
}
1105+
}
1106+
Builder.CreateStore(Val, ReturnValue);
10941107
} else {
10951108
switch (getEvaluationKind(RV->getType())) {
10961109
case TEK_Scalar:
1097-
Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
1110+
{
1111+
llvm::Value *Val = EmitScalarExpr(RV);
1112+
if (!getenv("DISABLE_INFER_AS")) {
1113+
if (auto *PtrTy = dyn_cast<llvm::PointerType>(Val->getType())) {
1114+
auto *ExpectedPtrType =
1115+
cast<llvm::PointerType>(ReturnValue.getType()->getElementType());
1116+
unsigned ValueAS = PtrTy->getAddressSpace();
1117+
unsigned ExpectedAS = ExpectedPtrType->getAddressSpace();
1118+
if (ValueAS != ExpectedAS) {
1119+
Val = Builder.CreatePointerBitCastOrAddrSpaceCast(
1120+
Val, ExpectedPtrType);
1121+
}
1122+
}
1123+
}
1124+
Builder.CreateStore(Val, ReturnValue);
10981125
break;
1126+
}
10991127
case TEK_Complex:
11001128
EmitComplexExprIntoLValue(RV, MakeAddrLValue(ReturnValue, RV->getType()),
11011129
/*isInit*/ true);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -disable-llvm-passes -S -emit-llvm -x c++ %s -o - | FileCheck %s
2+
3+
struct A {
4+
int B[42];
5+
};
6+
7+
const char *ret_char() {
8+
return "N";
9+
}
10+
// CHECK: ret i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0) to i8 addrspace(4)*)
11+
12+
const char *ret_arr() {
13+
static char Arr[42];
14+
return Arr;
15+
}
16+
// CHECK: ret i8 addrspace(4)* getelementptr inbounds ([42 x i8], [42 x i8] addrspace(4)* addrspacecast ([42 x i8] addrspace(1)* @{{.*}}ret_arr{{.*}}Arr to [42 x i8] addrspace(4)*), i64 0, i64 0)
17+
18+
const char &ret_ref() {
19+
static char a = 'A';
20+
return a;
21+
}
22+
// CHECK: ret i8 addrspace(4)* addrspacecast (i8 addrspace(1)* @{{.*}}ret_ref{{.*}} to i8 addrspace(4)*)
23+
24+
A ret_agg() {
25+
A a;
26+
return a;
27+
}
28+
// CHECK: define spir_func void @{{.*}}ret_agg{{.*}}(%struct.{{.*}}.A addrspace(4)* noalias sret %agg.result)
29+
30+
template <typename name, typename Func>
31+
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
32+
kernelFunc();
33+
}
34+
35+
int main() {
36+
kernel_single_task<class kernel>([]() {
37+
ret_char();
38+
ret_arr();
39+
ret_ref();
40+
ret_agg();
41+
});
42+
return 0;
43+
}

0 commit comments

Comments
 (0)