@@ -290,7 +290,6 @@ void SPIRVEmitIntrinsics::insertPtrCastInstr(Instruction *I) {
290
290
Value *Pointer;
291
291
Type *ExpectedElementType;
292
292
unsigned OperandToReplace;
293
- bool AllowCastingToChar = false ;
294
293
295
294
StoreInst *SI = dyn_cast<StoreInst>(I);
296
295
if (SI && F->getCallingConv () == CallingConv::SPIR_KERNEL &&
@@ -308,7 +307,6 @@ void SPIRVEmitIntrinsics::insertPtrCastInstr(Instruction *I) {
308
307
Pointer = Arg;
309
308
ExpectedElementType = IntegerType::getInt8Ty (F->getContext ());
310
309
OperandToReplace = 0 ;
311
- AllowCastingToChar = true ;
312
310
} else if (SI) {
313
311
Pointer = SI->getPointerOperand ();
314
312
ExpectedElementType = SI->getValueOperand ()->getType ();
@@ -390,10 +388,20 @@ void SPIRVEmitIntrinsics::insertPtrCastInstr(Instruction *I) {
390
388
}
391
389
392
390
// Do not emit spv_ptrcast if it would cast to the default pointer element
393
- // type (i8) of the same address space.
394
- if (ExpectedElementType->isIntegerTy (8 ) && !AllowCastingToChar)
391
+ // type (i8) of the same address space. In case of OpenCL kernels, make sure
392
+ // i8 is the pointer element type defined for the given kernel argument.
393
+ if (ExpectedElementType->isIntegerTy (8 ) &&
394
+ F->getCallingConv () != CallingConv::SPIR_KERNEL)
395
395
return ;
396
396
397
+ Argument *Arg = dyn_cast<Argument>(Pointer);
398
+ if (ExpectedElementType->isIntegerTy (8 ) &&
399
+ F->getCallingConv () == CallingConv::SPIR_KERNEL && Arg) {
400
+ MDString *ArgType = getOCLKernelArgType (*Arg->getParent (), Arg->getArgNo ());
401
+ if (ArgType && ArgType->getString ().starts_with (" uchar*" ))
402
+ return ;
403
+ }
404
+
397
405
// If this would be the first spv_ptrcast, the pointer's defining instruction
398
406
// requires spv_assign_ptr_type and does not already have one, do not emit
399
407
// spv_ptrcast and emit spv_assign_ptr_type instead.
0 commit comments