1515
1616#include " gen/abi/generic.h"
1717
18+ #include " ir/irfuncty.h"
19+
20+ #include " llvm/IR/IntrinsicsSPIRV.h"
21+
1822struct DComputePointerRewrite : ABIRewrite {
1923 LLValue *put (DValue *v, bool isLValueExp, bool ) override {
2024 LLValue *address = DtoLVal (v);
@@ -23,12 +27,47 @@ struct DComputePointerRewrite : ABIRewrite {
2327
2428 LLValue *getLVal (Type *dty, LLValue *v) override {
2529 LLValue *mem = DtoAlloca (dty, " .DComputePointerRewrite_param_storage" );
26- DtoStore (v, mem);
30+ LLType *realStructTy = DtoMemType (dty);
31+ LLValue *field = DtoGEP (realStructTy, mem, 0u , 0u );
32+
33+ if (gIR && gIR ->dcomputetarget &&
34+ gIR ->dcomputetarget ->target == DComputeTarget::ID ::Vulkan) {
35+ auto ptrOpt = toDcomputePointer (static_cast <TypeStruct *>(dty)->sym );
36+ assert (ptrOpt && " DComputePointerRewrite expects ldc.dcompute.Pointer" );
37+ const auto &ptr = *ptrOpt;
38+ llvm::Type *elemTy = DtoType (ptr.type );
39+ int realAS = gIR ->dcomputetarget ->mapping [ptr.addrspace ];
40+
41+ llvm::Value *ofType = llvm::PoisonValue::get (elemTy);
42+ llvm::Metadata *md = llvm::ValueAsMetadata::get (ofType);
43+ llvm::Value *mdVal = llvm::MetadataAsValue::get (gIR ->context (), md);
44+
45+ #if LLVM_VERSION_MAJOR >= 20
46+ llvm::Function *assignFn = llvm::Intrinsic::getOrInsertDeclaration (
47+ &gIR ->module , llvm::Intrinsic::spv_assign_ptr_type, {v->getType ()});
48+ #else
49+ llvm::Function *assignFn = llvm::Intrinsic::getDeclaration (
50+ &gIR ->module , llvm::Intrinsic::spv_assign_ptr_type, {v->getType ()});
51+ #endif
52+ gIR ->ir ->CreateCall (assignFn->getFunctionType (), assignFn,
53+ {v, mdVal, llvm::ConstantInt::get (llvm::Type::getInt32Ty (gIR ->context ()), realAS)});
54+ }
55+
56+ DtoStore (v, field);
2757 return mem;
2858 }
2959
3060 LLType *type (Type *t) override {
31- auto ptr = toDcomputePointer (static_cast <TypeStruct *>(t)->sym );
32- return ptr->toLLVMType (true );
61+ auto ptrOpt = toDcomputePointer (static_cast <TypeStruct *>(t)->sym );
62+ assert (ptrOpt && " DComputePointerRewrite expects ldc.dcompute.Pointer" );
63+ return ptrOpt->toLLVMType (true );
64+ }
65+
66+ void applyTo (IrFuncTyArg &arg, LLType *finalLType = nullptr ) override {
67+ arg.rewrite = this ;
68+ arg.ltype = finalLType ? finalLType : this ->type (arg.type );
69+ arg.byref = false ;
70+ arg.attrs .removeAttribute (llvm::Attribute::Dereferenceable);
71+ arg.attrs .removeAttribute (llvm::Attribute::NonNull);
3372 }
3473};
0 commit comments