@@ -3684,17 +3684,17 @@ Instruction *SPIRVToLLVM::transBuiltinFromInst(const std::string &FuncName,
36843684 std::vector<Type *> ArgTys =
36853685 transTypeVector (SPIRVInstruction::getOperandTypes (Ops), true );
36863686
3687- auto Ptr = findFirstPtrType (ArgTys);
3688- if (Ptr < ArgTys.size () &&
3689- BI->getValueType (Ops[Ptr ]->getId ())->isTypeUntypedPointerKHR ()) {
3687+ unsigned PtrIdx = findFirstPtrType (ArgTys);
3688+ if (PtrIdx < ArgTys.size () &&
3689+ BI->getValueType (Ops[PtrIdx ]->getId ())->isTypeUntypedPointerKHR ()) {
36903690 // Special handling for "truly" untyped pointers to preserve correct
36913691 // builtin mangling of atomic and matrix operations.
36923692 if (isAtomicOpCodeUntypedPtrSupported (OC)) {
36933693 auto *AI = static_cast <SPIRVAtomicInstBase *>(BI);
3694- ArgTys[Ptr ] = TypedPointerType::get (
3694+ ArgTys[PtrIdx ] = TypedPointerType::get (
36953695 transType (AI->getSemanticType ()),
3696- SPIRSPIRVAddrSpaceMap::rmap (
3697- BI-> getValueType (Ops[Ptr]-> getId ()) ->getPointerStorageClass ()));
3696+ SPIRSPIRVAddrSpaceMap::rmap (BI-> getValueType (Ops[PtrIdx]-> getId ())
3697+ ->getPointerStorageClass ()));
36983698 }
36993699 }
37003700
@@ -3709,51 +3709,8 @@ Instruction *SPIRVToLLVM::transBuiltinFromInst(const std::string &FuncName,
37093709 continue ;
37103710 }
37113711 if (OpTy->isTypeUntypedPointerKHR ()) {
3712- auto *Val = transValue (Ops[I], BB->getParent (), BB);
3713- Val = Val->stripPointerCasts ();
3714- if (isUntypedAccessChainOpCode (Ops[I]->getOpCode ())) {
3715- SPIRVType *BaseTy =
3716- reinterpret_cast <SPIRVAccessChainBase *>(Ops[I])->getBaseType ();
3717-
3718- Type *Ty = nullptr ;
3719- if (BaseTy->isTypeArray ())
3720- Ty = transType (BaseTy->getArrayElementType ());
3721- else if (BaseTy->isTypeVector ())
3722- Ty = transType (BaseTy->getVectorComponentType ());
3723- else
3724- Ty = transType (BaseTy);
3725- ArgTys[I] = TypedPointerType::get (
3726- Ty, SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3727- } else if (auto *GEP = dyn_cast<GetElementPtrInst>(Val)) {
3728- ArgTys[I] = TypedPointerType::get (
3729- GEP->getSourceElementType (),
3730- SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3731- } else if (Ops[I]->getOpCode () == OpUntypedVariableKHR) {
3732- SPIRVUntypedVariableKHR *UV =
3733- static_cast <SPIRVUntypedVariableKHR *>(Ops[I]);
3734- Type *Ty = transType (UV->getDataType ());
3735- ArgTys[I] = TypedPointerType::get (
3736- Ty, SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3737- } else if (auto *AI = dyn_cast<AllocaInst>(Val)) {
3738- ArgTys[I] = TypedPointerType::get (
3739- AI->getAllocatedType (),
3740- SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3741- } else if (Ops[I]->getOpCode () == OpFunctionParameter &&
3742- !RetTy->isVoidTy ()) {
3743- // Pointer could be a function parameter. Assume that the type of
3744- // the pointer is the same as the return type.
3745- Type *Ty = nullptr ;
3746- // it return type is array type, assign its element type to Ty
3747- if (RetTy->isArrayTy ())
3748- Ty = RetTy->getArrayElementType ();
3749- else if (RetTy->isVectorTy ())
3750- Ty = cast<VectorType>(RetTy)->getElementType ();
3751- else
3752- Ty = RetTy;
3753-
3754- ArgTys[I] = TypedPointerType::get (
3755- Ty, SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3756- }
3712+ if (Type *NewPtrTy = getTypedPtrFromUntypedOperand (Ops[I], RetTy))
3713+ ArgTys[I] = NewPtrTy;
37573714 }
37583715 }
37593716 }
@@ -3825,6 +3782,55 @@ SPIRVToLLVM::SPIRVToLLVM(Module *LLVMModule, SPIRVModule *TheSPIRVModule)
38253782 DbgTran.reset (new SPIRVToLLVMDbgTran (TheSPIRVModule, LLVMModule, this ));
38263783}
38273784
3785+ Type *SPIRVToLLVM::getTypedPtrFromUntypedOperand (SPIRVValue *Val, Type *RetTy) {
3786+ Type *Ty = nullptr ;
3787+ Op OC = Val->getOpCode ();
3788+ if (isUntypedAccessChainOpCode (OC)) {
3789+ SPIRVType *BaseTy =
3790+ reinterpret_cast <SPIRVAccessChainBase *>(Val)->getBaseType ();
3791+ if (BaseTy->isTypeArray ())
3792+ Ty = transType (BaseTy->getArrayElementType ());
3793+ else if (BaseTy->isTypeVector ())
3794+ Ty = transType (BaseTy->getVectorComponentType ());
3795+ else
3796+ Ty = transType (BaseTy);
3797+ } else if (OC == OpUntypedVariableKHR) {
3798+ auto *UV = static_cast <SPIRVUntypedVariableKHR *>(Val);
3799+ Ty = transType (UV->getDataType ());
3800+ } else if (OC == OpFunctionParameter && !RetTy->isVoidTy ()) {
3801+ // Pointer could be a function parameter. Assume that the type of
3802+ // the pointer is the same as the return type.
3803+ // If return type is array/vector type, assign its element type to Ty.
3804+ if (RetTy->isArrayTy ())
3805+ Ty = RetTy->getArrayElementType ();
3806+ else if (RetTy->isVectorTy ())
3807+ Ty = cast<VectorType>(RetTy)->getElementType ();
3808+ else
3809+ Ty = RetTy;
3810+ }
3811+
3812+ unsigned AddrSpace =
3813+ SPIRSPIRVAddrSpaceMap::rmap (Val->getType ()->getPointerStorageClass ());
3814+ if (Ty)
3815+ return TypedPointerType::get (Ty, AddrSpace);
3816+
3817+ // If we couldn't infer a better element type, attempt to derive from an
3818+ // already translated LLVM value (GEP, Alloca, etc.).
3819+ if (Value *V = getTranslatedValue (Val)) {
3820+ V = V->stripPointerCasts ();
3821+ if (auto *GEP = dyn_cast<GetElementPtrInst>(V))
3822+ Ty = GEP->getSourceElementType ();
3823+ else if (auto *AI = dyn_cast<AllocaInst>(V))
3824+ Ty = AI->getAllocatedType ();
3825+ }
3826+
3827+ if (Ty)
3828+ return TypedPointerType::get (Ty, AddrSpace);
3829+ if (!RetTy->isVoidTy ())
3830+ return TypedPointerType::get (RetTy, AddrSpace);
3831+ return nullptr ;
3832+ }
3833+
38283834std::string getSPIRVFuncSuffix (SPIRVInstruction *BI) {
38293835 std::string Suffix = " " ;
38303836 if (BI->getOpCode () == OpCreatePipeFromPipeStorage) {
@@ -5299,20 +5305,41 @@ Instruction *SPIRVToLLVM::transOCLBuiltinFromExtInst(SPIRVExtInst *BC,
52995305 assert (BM->getBuiltinSet (BC->getExtSetId ()) == SPIRVEIS_OpenCL &&
53005306 " Not OpenCL extended instruction" );
53015307
5308+ Type *RetTy = transType (BC->getType ());
53025309 std::vector<Type *> ArgTypes = transTypeVector (BC->getArgTypes (), true );
5303- for (unsigned I = 0 ; I < ArgTypes.size (); I++) {
5304- // Special handling for "truly" untyped pointers to preserve correct OCL
5305- // bultin mangling.
5306- if (isa<PointerType>(ArgTypes[I]) &&
5307- BC->getArgValue (I)->isUntypedVariable ()) {
5308- auto *BVar = static_cast <SPIRVUntypedVariableKHR *>(BC->getArgValue (I));
5309- ArgTypes[I] = TypedPointerType::get (
5310- transType (BVar->getDataType ()),
5311- SPIRSPIRVAddrSpaceMap::rmap (BVar->getStorageClass ()));
5310+ // Special handling for "truly" untyped pointers to preserve correct
5311+ // OCL builtin mangling.
5312+ unsigned PtrIdx = findFirstPtrType (ArgTypes);
5313+ if (PtrIdx < ArgTypes.size () &&
5314+ BC->getArgValue (PtrIdx)->getType ()->isTypeUntypedPointerKHR ()) {
5315+ switch (ExtOp) {
5316+ case OpenCLLIB::Frexp:
5317+ case OpenCLLIB::Remquo:
5318+ case OpenCLLIB::Lgamma_r: {
5319+ // These builtins require their pointer arguments to point to i32 or
5320+ // vector of i32 values.
5321+ Type *DataType = Type::getInt32Ty (*Context);
5322+ if (RetTy->isVectorTy ())
5323+ DataType = VectorType::get (DataType,
5324+ cast<VectorType>(RetTy)->getElementCount ());
5325+ ArgTypes[PtrIdx] = TypedPointerType::get (
5326+ DataType, cast<PointerType>(ArgTypes[PtrIdx])->getAddressSpace ());
5327+ } break ;
5328+ case OpenCLLIB::Printf: {
5329+ // Printf's format argument type is always i8*.
5330+ ArgTypes[PtrIdx] = TypedPointerType::get (
5331+ Type::getInt8Ty (*Context),
5332+ cast<PointerType>(ArgTypes[PtrIdx])->getAddressSpace ());
5333+ } break ;
5334+ default : {
5335+ Type *NewPtrTy =
5336+ getTypedPtrFromUntypedOperand (BC->getArgValue (PtrIdx), RetTy);
5337+ if (NewPtrTy)
5338+ ArgTypes[PtrIdx] = NewPtrTy;
5339+ }
53125340 }
53135341 }
53145342
5315- Type *RetTy = transType (BC->getType ());
53165343 std::string MangledName =
53175344 getSPIRVFriendlyIRFunctionName (ExtOp, ArgTypes, RetTy);
53185345 opaquifyTypedPointers (ArgTypes);
0 commit comments