Skip to content

Commit a47242e

Browse files
sndmitrievromanovvlad
authored andcommitted
[SYCL] Addrspace cast phi operands when lowering conditional operator
Make sure that all operands of phi instruction that is generated while lowering conditional operator have the same type. This fixes compiler assertion. Signed-off-by: Sergey Dmitriev <[email protected]>
1 parent 78d9957 commit a47242e

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

clang/lib/CodeGen/CGExpr.cpp

+29-4
Original file line numberDiff line numberDiff line change
@@ -4279,10 +4279,35 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
42794279
EmitBlock(contBlock);
42804280

42814281
if (lhs && rhs) {
4282-
llvm::PHINode *phi = Builder.CreatePHI(lhs->getPointer()->getType(),
4283-
2, "cond-lvalue");
4284-
phi->addIncoming(lhs->getPointer(), lhsBlock);
4285-
phi->addIncoming(rhs->getPointer(), rhsBlock);
4282+
llvm::Value *lhsPtr = lhs->getPointer();
4283+
llvm::Value *rhsPtr = rhs->getPointer();
4284+
if (rhsPtr->getType() != lhsPtr->getType()) {
4285+
if (!getLangOpts().SYCLIsDevice)
4286+
llvm_unreachable(
4287+
"Unable to find a common address space for two pointers.");
4288+
4289+
auto CastToAS = [](llvm::Value *V, llvm::BasicBlock *BB, unsigned AS) {
4290+
auto *Ty = cast<llvm::PointerType>(V->getType());
4291+
if (Ty->getAddressSpace() == AS)
4292+
return V;
4293+
llvm::IRBuilder<> Builder(BB->getTerminator());
4294+
auto *TyAS = llvm::PointerType::get(Ty->getElementType(), AS);
4295+
return Builder.CreatePointerBitCastOrAddrSpaceCast(V, TyAS);
4296+
};
4297+
4298+
// Language rules define if it is legal to cast from one address space
4299+
// to another, and which address space we should use as a "common
4300+
// denominator". In SYCL, generic address space overlaps with all other
4301+
// address spaces.
4302+
unsigned GenericAS =
4303+
getContext().getTargetAddressSpace(LangAS::opencl_generic);
4304+
4305+
lhsPtr = CastToAS(lhsPtr, lhsBlock, GenericAS);
4306+
rhsPtr = CastToAS(rhsPtr, rhsBlock, GenericAS);
4307+
}
4308+
llvm::PHINode *phi = Builder.CreatePHI(lhsPtr->getType(), 2, "cond-lvalue");
4309+
phi->addIncoming(lhsPtr, lhsBlock);
4310+
phi->addIncoming(rhsPtr, rhsBlock);
42864311
Address result(phi, std::min(lhs->getAlignment(), rhs->getAlignment()));
42874312
AlignmentSource alignSource =
42884313
std::max(lhs->getBaseInfo().getAlignmentSource(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clang_cc1 -x c++ -triple spir64-unknown-linux-sycldevice -std=c++11 -disable-llvm-passes -fsycl-is-device -emit-llvm %s -o - | FileCheck %s
2+
3+
// CHECK: [[STYPE:%.+]] = type { i16 }
4+
struct S {
5+
unsigned short x;
6+
};
7+
8+
S foo(bool cond, S &lhs, S rhs) {
9+
// CHECK-LABEL:@_Z3foobR1SS_
10+
// CHECK: br i1 {{.+}}, label %[[BTRUE:.+]], label %[[BFALSE:.+]]
11+
//
12+
// CHECK: [[BTRUE]]:
13+
// CHECK: %[[LHS:.+]] = load [[STYPE]] addrspace(4)*, [[STYPE]] addrspace(4)**
14+
// CHECK: br label %[[BEND:.+]]
15+
//
16+
// CHECK: [[BFALSE]]:
17+
// CHECK: %[[RHS:.+]] = addrspacecast [[STYPE]]* {{.+}} to [[STYPE]] addrspace(4)*
18+
// CHECK: br label %[[BEND]]
19+
//
20+
// CHECK: [[BEND]]:
21+
// CHECK: %{{.+}} = phi [[STYPE]] addrspace(4)* [ %[[LHS]], %[[BTRUE]] ], [ %[[RHS]], %[[BFALSE]] ]
22+
S val = cond ? lhs : rhs;
23+
return val;
24+
}
25+
26+
template <typename name, typename Func>
27+
__attribute__((sycl_kernel)) void kernel(Func kernelFunc) {
28+
kernelFunc();
29+
}
30+
31+
int main() {
32+
kernel<class fake_kernel>([]() {
33+
S lhs, rhs;
34+
foo(true, lhs, rhs);
35+
});
36+
return 0;
37+
}

0 commit comments

Comments
 (0)