@@ -4160,6 +4160,52 @@ static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
4160
4160
// exist in the source-level program.
4161
4161
}
4162
4162
4163
+ static Value *insertAddressSpaceCast (Value *V, unsigned NewAS) {
4164
+ auto *VTy = cast<llvm::PointerType>(V->getType ());
4165
+ if (VTy->getAddressSpace () == NewAS)
4166
+ return V;
4167
+
4168
+ llvm::PointerType *VTyNewAS =
4169
+ llvm::PointerType::get (VTy->getElementType (), NewAS);
4170
+
4171
+ if (auto *Constant = dyn_cast<llvm::Constant>(V))
4172
+ return llvm::ConstantExpr::getAddrSpaceCast (Constant, VTyNewAS);
4173
+
4174
+ llvm::Instruction *NewV =
4175
+ new llvm::AddrSpaceCastInst (V, VTyNewAS, V->getName () + " .ascast" );
4176
+ NewV->insertAfter (cast<llvm::Instruction>(V));
4177
+ return NewV;
4178
+ }
4179
+
4180
+ static void ensureSameAddrSpace (Value *&RHS, Value *&LHS,
4181
+ bool CanInsertAddrspaceCast,
4182
+ const LangOptions &Opts,
4183
+ const ASTContext &Context) {
4184
+ if (RHS->getType () == LHS->getType ())
4185
+ return ;
4186
+
4187
+ auto *RHSTy = dyn_cast<llvm::PointerType>(RHS->getType ());
4188
+ auto *LHSTy = dyn_cast<llvm::PointerType>(LHS->getType ());
4189
+ if (!RHSTy || !LHSTy || RHSTy->getAddressSpace () == LHSTy->getAddressSpace ())
4190
+ return ;
4191
+
4192
+ if (!CanInsertAddrspaceCast)
4193
+ // Pointers have different address spaces and we cannot do anything with
4194
+ // this.
4195
+ llvm_unreachable (" Pointers are expected to have the same address space." );
4196
+
4197
+ // Language rules define if it is legal to cast from one address space to
4198
+ // another, and which address space we should use as a "common
4199
+ // denominator". In SYCL, generic address space overlaps with all other
4200
+ // address spaces.
4201
+ if (Opts.SYCLIsDevice ) {
4202
+ unsigned GenericAS = Context.getTargetAddressSpace (LangAS::opencl_generic);
4203
+ RHS = insertAddressSpaceCast (RHS, GenericAS);
4204
+ LHS = insertAddressSpaceCast (LHS, GenericAS);
4205
+ } else
4206
+ llvm_unreachable (" Unable to find a common address space for "
4207
+ " two pointers." );
4208
+ }
4163
4209
4164
4210
Value *ScalarExprEmitter::
4165
4211
VisitAbstractConditionalOperator (const AbstractConditionalOperator *E) {
@@ -4256,6 +4302,15 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
4256
4302
assert (!RHS && " LHS and RHS types must match" );
4257
4303
return nullptr ;
4258
4304
}
4305
+
4306
+ // Expressions may have the same addrspace in AST, but different address
4307
+ // space in LLVM IR, in which case an addrspacecast should be valid.
4308
+ bool CanInsertAddrspaceCast = rhsExpr->getType ().getAddressSpace () ==
4309
+ lhsExpr->getType ().getAddressSpace ();
4310
+
4311
+ ensureSameAddrSpace (RHS, LHS, CanInsertAddrspaceCast, CGF.getLangOpts (),
4312
+ CGF.getContext ());
4313
+
4259
4314
return Builder.CreateSelect (CondV, LHS, RHS, " cond" );
4260
4315
}
4261
4316
@@ -4290,6 +4345,14 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
4290
4345
if (!RHS)
4291
4346
return LHS;
4292
4347
4348
+ // Expressions may have the same addrspace in AST, but different address
4349
+ // space in LLVM IR, in which case an addrspacecast should be valid.
4350
+ bool CanInsertAddrspaceCast = rhsExpr->getType ().getAddressSpace () ==
4351
+ lhsExpr->getType ().getAddressSpace ();
4352
+
4353
+ ensureSameAddrSpace (RHS, LHS, CanInsertAddrspaceCast, CGF.getLangOpts (),
4354
+ CGF.getContext ());
4355
+
4293
4356
// Create a PHI node for the real part.
4294
4357
llvm::PHINode *PN = Builder.CreatePHI (LHS->getType (), 2 , " cond" );
4295
4358
PN->addIncoming (LHS, LHSBlock);
0 commit comments