@@ -2467,13 +2467,18 @@ SPIRVLifetimeStart *LTStart = static_cast<SPIRVLifetimeStart *>(BV);
24672467 BaseSPVTy->isTypeCooperativeMatrixKHR ())) {
24682468 return mapValue (BV, transSPIRVBuiltinFromInst (AC, BB));
24692469 }
2470- Type *BaseTy =
2471- BaseSPVTy->isTypeVector ()
2472- ? transType (
2473- BaseSPVTy->getVectorComponentType ()->getPointerElementType ())
2474- : BaseSPVTy->isTypePointer ()
2475- ? transType (BaseSPVTy->getPointerElementType ())
2476- : transType (BaseSPVTy);
2470+ Type *BaseTy = nullptr ;
2471+ if (BaseSPVTy->isTypeVector ()) {
2472+ auto *VecCompTy = BaseSPVTy->getVectorComponentType ();
2473+ if (VecCompTy->isTypePointer ())
2474+ BaseTy = transType (VecCompTy->getPointerElementType ());
2475+ else
2476+ BaseTy = transType (VecCompTy);
2477+ } else if (BaseSPVTy->isTypePointer ()) {
2478+ BaseTy = transType (BaseSPVTy->getPointerElementType ());
2479+ } else {
2480+ BaseTy = transType (BaseSPVTy);
2481+ }
24772482 auto Index = transValue (AC->getIndices (), F, BB);
24782483 if (!AC->hasPtrIndex ())
24792484 Index.insert (Index.begin (), getInt32 (M, 0 ));
@@ -3793,20 +3798,20 @@ Instruction *SPIRVToLLVM::transBuiltinFromInst(const std::string &FuncName,
37933798 std::vector<Type *> ArgTys =
37943799 transTypeVector (SPIRVInstruction::getOperandTypes (Ops), true );
37953800
3796- auto Ptr = findFirstPtrType (ArgTys);
3797- if (Ptr < ArgTys.size () &&
3798- BI->getValueType (Ops[Ptr ]->getId ())->isTypeUntypedPointerKHR ()) {
3801+ unsigned PtrIdx = findFirstPtrType (ArgTys);
3802+ if (PtrIdx < ArgTys.size () &&
3803+ BI->getValueType (Ops[PtrIdx ]->getId ())->isTypeUntypedPointerKHR ()) {
37993804 // Special handling for "truly" untyped pointers to preserve correct
38003805 // builtin mangling of atomic and matrix operations.
38013806 if (isAtomicOpCodeUntypedPtrSupported (OC)) {
38023807 auto *AI = static_cast <SPIRVAtomicInstBase *>(BI);
3803- ArgTys[Ptr ] = TypedPointerType::get (
3808+ ArgTys[PtrIdx ] = TypedPointerType::get (
38043809 transType (AI->getSemanticType ()),
38053810 M->getTargetTriple ().getVendor () == Triple::VendorType::AMD
38063811 ? mapSPIRVAddrSpaceToAMDGPU (
3807- BI->getValueType (Ops[Ptr ]->getId ())->getPointerStorageClass ())
3812+ BI->getValueType (Ops[PtrIdx ]->getId ())->getPointerStorageClass ())
38083813 : SPIRSPIRVAddrSpaceMap::rmap (
3809- BI->getValueType (Ops[Ptr ]->getId ())->getPointerStorageClass ()));
3814+ BI->getValueType (Ops[PtrIdx ]->getId ())->getPointerStorageClass ()));
38103815 }
38113816 }
38123817
@@ -3821,51 +3826,8 @@ Instruction *SPIRVToLLVM::transBuiltinFromInst(const std::string &FuncName,
38213826 continue ;
38223827 }
38233828 if (OpTy->isTypeUntypedPointerKHR ()) {
3824- auto *Val = transValue (Ops[I], BB->getParent (), BB);
3825- Val = Val->stripPointerCasts ();
3826- if (isUntypedAccessChainOpCode (Ops[I]->getOpCode ())) {
3827- SPIRVType *BaseTy =
3828- reinterpret_cast <SPIRVAccessChainBase *>(Ops[I])->getBaseType ();
3829-
3830- Type *Ty = nullptr ;
3831- if (BaseTy->isTypeArray ())
3832- Ty = transType (BaseTy->getArrayElementType ());
3833- else if (BaseTy->isTypeVector ())
3834- Ty = transType (BaseTy->getVectorComponentType ());
3835- else
3836- Ty = transType (BaseTy);
3837- ArgTys[I] = TypedPointerType::get (
3838- Ty, SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3839- } else if (auto *GEP = dyn_cast<GetElementPtrInst>(Val)) {
3840- ArgTys[I] = TypedPointerType::get (
3841- GEP->getSourceElementType (),
3842- SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3843- } else if (Ops[I]->getOpCode () == OpUntypedVariableKHR) {
3844- SPIRVUntypedVariableKHR *UV =
3845- static_cast <SPIRVUntypedVariableKHR *>(Ops[I]);
3846- Type *Ty = transType (UV->getDataType ());
3847- ArgTys[I] = TypedPointerType::get (
3848- Ty, SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3849- } else if (auto *AI = dyn_cast<AllocaInst>(Val)) {
3850- ArgTys[I] = TypedPointerType::get (
3851- AI->getAllocatedType (),
3852- SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3853- } else if (Ops[I]->getOpCode () == OpFunctionParameter &&
3854- !RetTy->isVoidTy ()) {
3855- // Pointer could be a function parameter. Assume that the type of
3856- // the pointer is the same as the return type.
3857- Type *Ty = nullptr ;
3858- // it return type is array type, assign its element type to Ty
3859- if (RetTy->isArrayTy ())
3860- Ty = RetTy->getArrayElementType ();
3861- else if (RetTy->isVectorTy ())
3862- Ty = cast<VectorType>(RetTy)->getElementType ();
3863- else
3864- Ty = RetTy;
3865-
3866- ArgTys[I] = TypedPointerType::get (
3867- Ty, SPIRSPIRVAddrSpaceMap::rmap (OpTy->getPointerStorageClass ()));
3868- }
3829+ if (Type *NewPtrTy = getTypedPtrFromUntypedOperand (Ops[I], RetTy))
3830+ ArgTys[I] = NewPtrTy;
38693831 }
38703832 }
38713833 }
@@ -3956,6 +3918,58 @@ SPIRVToLLVM::SPIRVToLLVM(Module *LLVMModule, SPIRVModule *TheSPIRVModule)
39563918 DbgTran.reset (new SPIRVToLLVMDbgTran (TheSPIRVModule, LLVMModule, this ));
39573919}
39583920
3921+ Type *SPIRVToLLVM::getTypedPtrFromUntypedOperand (SPIRVValue *Val, Type *RetTy) {
3922+ Type *Ty = nullptr ;
3923+ Op OC = Val->getOpCode ();
3924+ if (isUntypedAccessChainOpCode (OC)) {
3925+ SPIRVType *BaseTy =
3926+ reinterpret_cast <SPIRVAccessChainBase *>(Val)->getBaseType ();
3927+ if (BaseTy->isTypeArray ())
3928+ Ty = transType (BaseTy->getArrayElementType ());
3929+ else if (BaseTy->isTypeVector ())
3930+ Ty = transType (BaseTy->getVectorComponentType ());
3931+ else
3932+ Ty = transType (BaseTy);
3933+ } else if (OC == OpUntypedVariableKHR) {
3934+ auto *UV = static_cast <SPIRVUntypedVariableKHR *>(Val);
3935+ Ty = transType (UV->getDataType ());
3936+ } else if (OC == OpFunctionParameter && !RetTy->isVoidTy ()) {
3937+ // Pointer could be a function parameter. Assume that the type of
3938+ // the pointer is the same as the return type.
3939+ // If return type is array/vector type, assign its element type to Ty.
3940+ if (RetTy->isArrayTy ())
3941+ Ty = RetTy->getArrayElementType ();
3942+ else if (RetTy->isVectorTy ())
3943+ Ty = cast<VectorType>(RetTy)->getElementType ();
3944+ else
3945+ Ty = RetTy;
3946+ }
3947+
3948+ StorageClass SC = Val->getType ()->getPointerStorageClass ();
3949+ unsigned AddrSpace =
3950+ (M->getTargetTriple ().getVendor () == Triple::VendorType::AMD)
3951+ ? mapSPIRVAddrSpaceToAMDGPU (SC) : SPIRSPIRVAddrSpaceMap::rmap (SC);
3952+
3953+ if (Ty)
3954+ return TypedPointerType::get (Ty, AddrSpace);
3955+
3956+ // If we couldn't infer a better element type, attempt to derive from an
3957+ // already translated LLVM value (GEP, Alloca, etc.).
3958+ if (Value *V = getTranslatedValue (Val)) {
3959+ V = V->stripPointerCasts ();
3960+ if (auto *GEP = dyn_cast<GetElementPtrInst>(V))
3961+ Ty = GEP->getSourceElementType ();
3962+ else if (auto *AI = dyn_cast<AllocaInst>(V))
3963+ Ty = AI->getAllocatedType ();
3964+ }
3965+
3966+ if (Ty)
3967+ return TypedPointerType::get (Ty, AddrSpace);
3968+ if (!RetTy->isVoidTy ())
3969+ return TypedPointerType::get (RetTy, AddrSpace);
3970+ return nullptr ;
3971+ }
3972+
39593973std::string getSPIRVFuncSuffix (SPIRVInstruction *BI) {
39603974 std::string Suffix = " " ;
39613975 if (BI->getOpCode () == OpCreatePipeFromPipeStorage) {
@@ -5701,25 +5715,44 @@ Instruction *SPIRVToLLVM::transOCLBuiltinFromExtInst(SPIRVExtInst *BC,
57015715 assert (BM->getBuiltinSet (BC->getExtSetId ()) == SPIRVEIS_OpenCL &&
57025716 " Not OpenCL extended instruction" );
57035717
5718+ Type *RetTy = transType (BC->getType ());
57045719 std::vector<Type *> ArgTypes = transTypeVector (BC->getArgTypes (), true );
5705- for (unsigned I = 0 ; I < ArgTypes.size (); I++) {
5706- // Special handling for "truly" untyped pointers to preserve correct OCL
5707- // bultin mangling.
5708- if (isa<PointerType>(ArgTypes[I]) &&
5709- BC->getArgValue (I)->isUntypedVariable ()) {
5710- auto *BVar = static_cast <SPIRVUntypedVariableKHR *>(BC->getArgValue (I));
5711- ArgTypes[I] = TypedPointerType::get (
5712- transType (BVar->getDataType ()),
5713- (M->getTargetTriple ().getVendor () == Triple::VendorType::AMD)
5714- ? mapSPIRVAddrSpaceToAMDGPU (BVar->getStorageClass ())
5715- : SPIRSPIRVAddrSpaceMap::rmap (BVar->getStorageClass ()));
5720+ // Special handling for "truly" untyped pointers to preserve correct
5721+ // OCL builtin mangling.
5722+ unsigned PtrIdx = findFirstPtrType (ArgTypes);
5723+ if (PtrIdx < ArgTypes.size () &&
5724+ BC->getArgValue (PtrIdx)->getType ()->isTypeUntypedPointerKHR ()) {
5725+ switch (ExtOp) {
5726+ case OpenCLLIB::Frexp:
5727+ case OpenCLLIB::Remquo:
5728+ case OpenCLLIB::Lgamma_r: {
5729+ // These builtins require their pointer arguments to point to i32 or
5730+ // vector of i32 values.
5731+ Type *DataType = Type::getInt32Ty (*Context);
5732+ if (RetTy->isVectorTy ())
5733+ DataType = VectorType::get (DataType,
5734+ cast<VectorType>(RetTy)->getElementCount ());
5735+ ArgTypes[PtrIdx] = TypedPointerType::get (
5736+ DataType, cast<PointerType>(ArgTypes[PtrIdx])->getAddressSpace ());
5737+ } break ;
5738+ case OpenCLLIB::Printf: {
5739+ // Printf's format argument type is always i8*.
5740+ ArgTypes[PtrIdx] = TypedPointerType::get (
5741+ Type::getInt8Ty (*Context),
5742+ cast<PointerType>(ArgTypes[PtrIdx])->getAddressSpace ());
5743+ } break ;
5744+ default : {
5745+ Type *NewPtrTy =
5746+ getTypedPtrFromUntypedOperand (BC->getArgValue (PtrIdx), RetTy);
5747+ if (NewPtrTy)
5748+ ArgTypes[PtrIdx] = NewPtrTy;
5749+ }
57165750 }
57175751 }
5718-
5719- Type *RetTy = transType (BC->getType ());
57205752 if (M->getTargetTriple ().getVendor () == Triple::VendorType::AMD)
57215753 return transLLVMFromExtInst (
57225754 *this , ExtOp, BC, RetTy, std::move (ArgTypes), BB);
5755+
57235756 std::string MangledName =
57245757 getSPIRVFriendlyIRFunctionName (ExtOp, ArgTypes, RetTy);
57255758 opaquifyTypedPointers (ArgTypes);
0 commit comments