From 531f00c0bd1a84af0b2805036fc3b2b98817f2eb Mon Sep 17 00:00:00 2001 From: Pham Quang Ha Date: Tue, 12 May 2026 12:30:09 +0700 Subject: [PATCH 1/7] Squashed commit of the following: commit 4314ddcbee8d65049675fb5d33cf71241d3a8bfd Merge: 29789c7426 79976be912 Author: Pham Quang Ha Date: Tue May 12 11:50:28 2026 +0700 Merge remote-tracking branch 'upstream/master' into pr-4958 commit 29789c7426f06a0297249cb74e6d9305f15a30df Author: Nicholas Wilson Date: Mon Oct 20 15:42:49 2025 +0800 [Dcompute] initial vulkan support --- CMakeLists.txt | 2 +- driver/dcomputecodegenerator.cpp | 8 ++ gen/abi/spirv.cpp | 9 ++ gen/abi/targets.h | 2 + gen/dcompute/target.h | 5 +- gen/dcompute/targetVulkan.cpp | 187 ++++++++++++++++++++++++++++ runtime/druntime/src/ldc/dcompute.d | 1 + 7 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 gen/dcompute/targetVulkan.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 83584dcae8a..bfd660f016d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ include(BuildDExecutable) find_package(LLVM 18.0 REQUIRED all-targets analysis asmparser asmprinter bitreader bitwriter codegen core - debuginfodwarf debuginfomsf debuginfopdb demangle + debuginfodwarf debuginfomsf debuginfopdb demangle frontendhlsl instcombine ipo instrumentation irreader libdriver linker lto mc mcdisassembler mcparser objcarcopts object option profiledata scalaropts selectiondag support tablegen target transformutils vectorize diff --git a/driver/dcomputecodegenerator.cpp b/driver/dcomputecodegenerator.cpp index 534757d4533..bba0dbd50ec 100644 --- a/driver/dcomputecodegenerator.cpp +++ b/driver/dcomputecodegenerator.cpp @@ -28,6 +28,14 @@ DComputeCodeGenManager::~DComputeCodeGenManager() {} DComputeTarget * DComputeCodeGenManager::createComputeTarget(const std::string &s) { + if (s.substr(0, 6) == "vulkan") { +#if LDC_LLVM_SUPPORTED_TARGET_SPIRV && LDC_LLVM_VER >= 2100 + //TODO version this for vulkan 1.3/1.4 + return createVulkanTarget(ctx, 0); +#else + error(Loc(), "LDC was not built with Vulkan DCompute support."); +#endif + } if (s.substr(0, 4) == "ocl-") { #if LDC_LLVM_SUPPORTED_TARGET_SPIRV #define OCL_VALID_VER_INIT 100, 110, 120, 200, 210, 220 diff --git a/gen/abi/spirv.cpp b/gen/abi/spirv.cpp index df8a487acc7..6a01dc9b96d 100644 --- a/gen/abi/spirv.cpp +++ b/gen/abi/spirv.cpp @@ -53,3 +53,12 @@ struct SPIRVTargetABI : TargetABI { }; TargetABI *createSPIRVABI() { return new SPIRVTargetABI(); } + +struct SPIRVVulkanTargetABI : SPIRVTargetABI { + + llvm::CallingConv::ID callingConv(FuncDeclaration *fdecl) override { + // The synthesised wrapper is SPIR_KERNEL + return llvm::CallingConv::SPIR_FUNC; + } +}; +TargetABI *createSPIRVVulkanABI() { return new SPIRVVulkanTargetABI(); } diff --git a/gen/abi/targets.h b/gen/abi/targets.h index 49098fe2579..cfb3d25ea9d 100644 --- a/gen/abi/targets.h +++ b/gen/abi/targets.h @@ -31,6 +31,8 @@ TargetABI *getRISCV64TargetABI(); TargetABI *createSPIRVABI(); +TargetABI *createSPIRVVulkanABI(); + TargetABI *getWin64TargetABI(); TargetABI *getX86_64TargetABI(); diff --git a/gen/dcompute/target.h b/gen/dcompute/target.h index 6ffdbea7678..34a156b3607 100644 --- a/gen/dcompute/target.h +++ b/gen/dcompute/target.h @@ -27,7 +27,7 @@ class DComputeTarget { public: llvm::LLVMContext &ctx; int tversion; // OpenCL or CUDA CC version:major*100 + minor*10 - enum class ID { Host = 0, OpenCL = 1, CUDA = 2 }; + enum class ID { Host = 0, OpenCL = 1, CUDA = 2, Vulkan = 3 }; ID target; // ID for codegen time conditional compilation. const char *short_name; const char *binSuffix; @@ -60,4 +60,7 @@ DComputeTarget *createCUDATarget(llvm::LLVMContext &c, int sm); #if LDC_LLVM_SUPPORTED_TARGET_SPIRV DComputeTarget *createOCLTarget(llvm::LLVMContext &c, int oclver); +#if LDC_LLVM_VER >= 2100 +DComputeTarget *createVulkanTarget(llvm::LLVMContext &c, int ver); +#endif #endif diff --git a/gen/dcompute/targetVulkan.cpp b/gen/dcompute/targetVulkan.cpp new file mode 100644 index 00000000000..75bf74995b5 --- /dev/null +++ b/gen/dcompute/targetVulkan.cpp @@ -0,0 +1,187 @@ +//===-- gen/dcomputetargetOCL.cpp -----------------------------------------===// +// +// LDC – the LLVM D compiler +// +// Parts of this file are adapted from CodeGenFunction.cpp (Clang, LLVM). +// Therefore, this file is distributed under the LLVM license. +// See the LICENSE file for details. +//===----------------------------------------------------------------------===// + +#if LDC_LLVM_SUPPORTED_TARGET_SPIRV && LDC_LLVM_VER >= 2100 + +#include "dmd/id.h" +#include "dmd/identifier.h" +#include "dmd/template.h" +#include "dmd/mangle.h" +#include "dmd/module.h" +#include "gen/abi/targets.h" +#include "gen/dcompute/target.h" +#include "gen/dcompute/druntime.h" +#include "gen/logger.h" +#include "gen/optimizer.h" +#include "driver/targetmachine.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Target/TargetMachine.h" +#include +#include + +using namespace dmd; + +namespace { +class TargetVulkan : public DComputeTarget { +public: + TargetVulkan(llvm::LLVMContext &c, int ver) + : DComputeTarget(c, ver, ID::Vulkan, "vulkan", "spv", createSPIRVVulkanABI(), + {{0, 1, 2, 3, 4}}) { + + _ir = new IRState("dcomputeTargetVulkan", ctx); + // "spirv-vulkan-foo"? foo = library, pixel, etc + std::string targTriple = "spirv1.6-unknown-vulkan1.3-compute"; + _ir->module.setTargetTriple(llvm::Triple(targTriple)); + + auto floatABI = ::FloatABI::Hard; + targetMachine = createTargetMachine( + targTriple, "spirv", "", {}, + ExplicitBitness::None, floatABI, + llvm::Reloc::Static, llvm::CodeModel::Medium, codeGenOptLevel(), false); + + _ir->module.setDataLayout(targetMachine->createDataLayout()); + + _ir->dcomputetarget = this; + } + + void addMetadata() override {} + + llvm::AttrBuilder buildKernAttrs(StructLiteralExp *kernAttr) { + auto b = llvm::AttrBuilder(ctx); + b.addAttribute("hlsl.shader", "compute"); + Expressions* elts = static_cast((*(kernAttr->elements))[0])->elements; + std::string numthreads = ""; + numthreads += std::to_string((*elts)[0]->toInteger()) + ","; + numthreads += std::to_string((*elts)[1]->toInteger()) + ","; + numthreads += std::to_string((*elts)[2]->toInteger()); + + b.addAttribute("hlsl.numthreads", numthreads); + // ? "hlsl.wavesize"="8,128,64" + // ? "hlsl.export" + return b; + } + llvm::Function *buildFunction(FuncDeclaration *fd) { + auto *void_func_void = llvm::FunctionType::get(llvm::Type::getVoidTy(ctx),{}, false); + auto linkage = llvm::GlobalValue::LinkageTypes::ExternalLinkage; + auto name = llvm::Twine(mangleExact(fd)) + llvm::Twine("_kernel"); + auto *f = llvm::Function::Create(void_func_void, linkage, name, _ir->module); + f->setCallingConv(llvm::CallingConv::SPIR_KERNEL); + return f; + } + llvm::Type *buildArgType(llvm::Function *llf, llvm::SmallVector &args, llvm::StringRef name) { + IF_LOG { + Logger::cout() << "buildArgType: " << *llf << std::endl; + } + llvm::FunctionType *tf = llf->getFunctionType(); + for (unsigned int i = 0; i < tf->getNumParams(); i++) { + llvm::Type *t = tf->getParamType(i); + if (t->isPointerTy()) + t = getI64Type(); // FIXME: 32 bit pointers on 32 but systems? + args[i] = t; + } + + IF_LOG { + for (auto *arg : args) { + Logger::cout() << *arg; + } + } + return llvm::StructType::create(ctx, args, name); + } + llvm::TargetExtType *buildTargetType(llvm::Type *argType) { + // TODO: Do we need to bother with a "spirv.Layout" here? + //auto *layout = llvm::TargetExtType::get(ctx, "spirv.Layout", ElemType,{}); + auto * ArrayType = llvm::ArrayType::get(argType, 0); + return llvm::TargetExtType::get(ctx, "spirv.VulkanBuffer", + {ArrayType}, + {12/*StorageClass*/, 0 /*isWritable*/}); + } + + llvm::Value *buildIntrinsicCall(IRBuilder<>& builder, llvm::StringRef dbg,llvm::StringRef name, + llvm::ArrayRef types, llvm::ArrayRef args) { + IF_LOG { + Logger::println("buildIntrinsicCall: %s", name.data()); + } + LOG_SCOPE + llvm::Function *intrinsic = llvm::Intrinsic::getOrInsertDeclaration(&_ir->module, + llvm::Intrinsic::lookupIntrinsicID(name), + types); + IF_LOG { + Logger::cout() << "intrinsic = " << *intrinsic << std::endl; + Logger::println("args:"); + LOG_SCOPE + for (auto* arg : args) { + Logger::cout() << *arg << std::endl; + } + } + + return builder.CreateCall(intrinsic->getFunctionType(), intrinsic, args, dbg); + } + + void addKernelMetadata(FuncDeclaration *fd, llvm::Function *llf, StructLiteralExp *kernAttr) override { + // Fake being HLSL + llvm::Function *f = buildFunction(fd); + f->addFnAttrs(buildKernAttrs(kernAttr)); + + llvm::SmallVector argTypes(llf->getFunctionType()->getNumParams()); + auto name = llvm::Twine(mangleExact(fd)) + llvm::Twine("_args"); + auto *argType = buildArgType(llf, argTypes, name.str()); + llvm::Type *targetType = buildTargetType(argType); + + auto bb = llvm::BasicBlock::Create(ctx, "", f); + llvm::IRBuilder<> builder(ctx); + builder.SetInsertPoint(bb); + + llvm::Value *i32zero = llvm::ConstantInt::get(getI32Type(), 0, false); + llvm::Value *i32one = llvm::ConstantInt::get(getI32Type(), 1, false); + llvm::Value *i1false = llvm::ConstantInt::get(llvm::Type::getInt1Ty(ctx), 0, false); + + // We can't use `DtoConstCString` here because it ends up in the wrong address space, So we use + // `getCachedStringLiteral` directly with an explicitly supplied addrspace of `0`. + // FIXME: call should have `notnull` attribute on pointer? + auto *handle = buildIntrinsicCall(builder, "handle","llvm.spv.resource.handlefrombinding", + {targetType}, + {i32zero, i32zero, i32one, i32zero, i1false, _ir->getCachedStringLiteral(name.str(), 0) }); + auto *p11 = llvm::PointerType::get(ctx, 11); + auto *pointer = buildIntrinsicCall(builder, "pointer", "llvm.spv.resource.getpointer", + {p11, targetType}, {handle, i32one}); + llvm::FunctionType *tf = llf->getFunctionType(); + IF_LOG { + Logger::cout() << "load pointer: " << *pointer << std::endl; + Logger::cout() << _ir->module.getDataLayout().getABITypeAlign(argType).value() << std::endl; + Logger::cout() << tf->getParamType(0)->getTypeID() << std::endl; + Logger::cout() << "done" << std::endl; + } + LOG_SCOPE + llvm::SmallVector args(tf->getNumParams()); + + auto *arg = builder.CreateAlignedLoad(argType, pointer, _ir->module.getDataLayout().getABITypeAlign(argType), false); + IF_LOG { + // Logger::cout() << "load elements from " << *arg << std::endl; + // Logger::cout() << "of type " << *argType << std::endl; + } + for (unsigned int i = 0; i < tf->getNumParams(); i++) { + args[i] = builder.CreateExtractValue(arg, {i}); + llvm::Type *t = tf->getParamType(i); + if (t->isPointerTy()) + args[i] = builder.CreateIntToPtr(args[i],t); + } + + builder.CreateCall(llf->getFunctionType(), llf, args); + builder.CreateRetVoid(); + IF_LOG Logger::cout() << *f << std::endl; + } + +}; +} // anonymous namespace. + +DComputeTarget *createVulkanTarget(llvm::LLVMContext &c, int ver) { + return new TargetVulkan(c, ver); +} + +#endif // LDC_LLVM_SUPPORTED_TARGET_SPIRV diff --git a/runtime/druntime/src/ldc/dcompute.d b/runtime/druntime/src/ldc/dcompute.d index 04002a43d91..f58a3021631 100644 --- a/runtime/druntime/src/ldc/dcompute.d +++ b/runtime/druntime/src/ldc/dcompute.d @@ -14,6 +14,7 @@ enum ReflectTarget : uint Host = 0, OpenCL = 1, CUDA = 2, + Vulkan = 3, } /** * The pseudo conditional compilation function. From cf93d058eeff315decf92a2134b033b3bb07411d Mon Sep 17 00:00:00 2001 From: Pham Quang Ha Date: Mon, 18 May 2026 09:11:06 +0700 Subject: [PATCH 2/7] init vulkan --- CMakeLists.txt | 5 ++--- driver/cl_options.cpp | 2 +- driver/dcomputecodegenerator.cpp | 17 ++++++++++++----- gen/dcompute/target.h | 2 +- gen/dcompute/targetVulkan.cpp | 5 ++--- gen/llvmhelpers.cpp | 2 +- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfd660f016d..0962528d7e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,9 +150,7 @@ if(MSVC) endif() endif() - if(${D_COMPILER_ID} STREQUAL "DigitalMars" AND (MSVC_VERSION GREATER 1800)) # VS 2015+ - append("-Llegacy_stdio_definitions.lib" DFLAGS_BASE) - endif() + append("-L/NODEFAULTLIB:libucrt -L/NODEFAULTLIB:libcmt -L/NODEFAULTLIB:libvcruntime -Lmsvcrt.lib -Lucrt.lib -Lvcruntime.lib -Llegacy_stdio_definitions.lib" DFLAGS_BASE) set(llvm_ob_flag) string(REGEX MATCH "/Ob[0-2]" llvm_ob_flag "${LLVM_CXXFLAGS}") @@ -1077,3 +1075,4 @@ install(FILES ${GCCBUILTINS} DESTINATION ${INCLUDE_INSTALL_DIR}/ldc) include (CMakeCPack.cmake) include (CPack) + \ No newline at end of file diff --git a/driver/cl_options.cpp b/driver/cl_options.cpp index c101cf199c8..a6ee58e92c3 100644 --- a/driver/cl_options.cpp +++ b/driver/cl_options.cpp @@ -756,7 +756,7 @@ cl::list dcomputeTargets("mdcompute-targets", cl::CommaSeparated, cl::desc("Generates code for the specified DCompute target" " list. Use 'ocl-xy0' for OpenCL x.y, and " - "'cuda-xy0' for CUDA CC x.y"), + "'cuda-xy0' for CUDA CC x.y, and 'vulkan-xy0' for Vulkan x.y"), cl::value_desc("targets")); cl::opt dcomputeFilePrefix("mdcompute-file-prefix", diff --git a/driver/dcomputecodegenerator.cpp b/driver/dcomputecodegenerator.cpp index bba0dbd50ec..b39046a7337 100644 --- a/driver/dcomputecodegenerator.cpp +++ b/driver/dcomputecodegenerator.cpp @@ -28,10 +28,16 @@ DComputeCodeGenManager::~DComputeCodeGenManager() {} DComputeTarget * DComputeCodeGenManager::createComputeTarget(const std::string &s) { - if (s.substr(0, 6) == "vulkan") { -#if LDC_LLVM_SUPPORTED_TARGET_SPIRV && LDC_LLVM_VER >= 2100 - //TODO version this for vulkan 1.3/1.4 - return createVulkanTarget(ctx, 0); + if (s.substr(0, 7) == "vulkan-") { +#if LDC_LLVM_SUPPORTED_TARGET_SPIRV && LLVM_VERSION_MAJOR >= 23 +#define VULKAN_VALID_VER_INIT 100, 110, 120, 130, 140 + const std::array valid_vulkan_versions = {{VULKAN_VALID_VER_INIT}}; + + const int v = atoi(s.c_str() + 7); + if (std::find(valid_vulkan_versions.begin(), valid_vulkan_versions.end(), v) != + valid_vulkan_versions.end()) { + return createVulkanTarget(ctx, v); + } #else error(Loc(), "LDC was not built with Vulkan DCompute support."); #endif @@ -72,9 +78,10 @@ DComputeCodeGenManager::createComputeTarget(const std::string &s) { error(Loc(), "Unrecognised or invalid DCompute targets: the format is ocl-xy0 " - "for OpenCl x.y and cuda-xy0 for CUDA CC x.y." + "for OpenCl x.y and cuda-xy0 for CUDA CC x.y, and vulkan-xy0 for Vulkan." #if LDC_LLVM_SUPPORTED_TARGET_SPIRV " Valid version strings for OpenCl are ocl-{" XSTR(OCL_VALID_VER_INIT) "}." + " Valid version strings for Vulkan are vulkan-{" XSTR(VULKAN_VALID_VER_INIT) "}." #endif #if LDC_LLVM_SUPPORTED_TARGET_NVPTX " Valid version strings for CUDA are cuda-{" XSTR(CUDA_VALID_VER_INIT) "}." diff --git a/gen/dcompute/target.h b/gen/dcompute/target.h index 34a156b3607..4d3667dcafc 100644 --- a/gen/dcompute/target.h +++ b/gen/dcompute/target.h @@ -60,7 +60,7 @@ DComputeTarget *createCUDATarget(llvm::LLVMContext &c, int sm); #if LDC_LLVM_SUPPORTED_TARGET_SPIRV DComputeTarget *createOCLTarget(llvm::LLVMContext &c, int oclver); -#if LDC_LLVM_VER >= 2100 +#if LLVM_VERSION_MAJOR >= 23 DComputeTarget *createVulkanTarget(llvm::LLVMContext &c, int ver); #endif #endif diff --git a/gen/dcompute/targetVulkan.cpp b/gen/dcompute/targetVulkan.cpp index 75bf74995b5..64e2bfcc70c 100644 --- a/gen/dcompute/targetVulkan.cpp +++ b/gen/dcompute/targetVulkan.cpp @@ -1,4 +1,4 @@ -//===-- gen/dcomputetargetOCL.cpp -----------------------------------------===// +//===-- gen/dcompute/targetVulkan.cpp -----------------------------------------===// // // LDC – the LLVM D compiler // @@ -7,8 +7,7 @@ // See the LICENSE file for details. //===----------------------------------------------------------------------===// -#if LDC_LLVM_SUPPORTED_TARGET_SPIRV && LDC_LLVM_VER >= 2100 - +#if LDC_LLVM_SUPPORTED_TARGET_SPIRV && LLVM_VERSION_MAJOR >= 23 #include "dmd/id.h" #include "dmd/identifier.h" #include "dmd/template.h" diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 3243ecedf5c..b932dbba154 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1365,7 +1365,7 @@ void printLabelName(std::ostream &target, const char *func_mangle, // note: quotes needed for Unicode target << '"' #if LLVM_VERSION_MAJOR >= 23 - << gTargetMachine->getMCAsmInfo().getPrivateLabelPrefix().str() + << gTargetMachine->getMCAsmInfo()->getPrivateLabelPrefix().str() #else << gTargetMachine->getMCAsmInfo()->getPrivateGlobalPrefix().str() #endif From 1cd7ccdf7bc3b3eb5f076bc05dd7d4472a170bf7 Mon Sep 17 00:00:00 2001 From: Pham Quang Ha Date: Sat, 23 May 2026 10:40:30 +0700 Subject: [PATCH 3/7] Update CMakeLists.txt and targetVulkan.cpp to include dcompute sources and adjust pointer type handling --- CMakeLists.txt | 4 ++-- gen/dcompute/targetVulkan.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0962528d7e3..cd9838e2a56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -309,8 +309,8 @@ configure_file(driver/ldc_version.d.in driver/ldc_version.d) file(GLOB_RECURSE FE_SRC_D dmd/*.d) file(GLOB_RECURSE FE_HDR dmd/*.h) file(GLOB_RECURSE FE_RES dmd/res/*.*) -file(GLOB_RECURSE GEN_SRC gen/*.cpp gen/abi/*.cpp) -file(GLOB_RECURSE GEN_HDR gen/*.h gen/abi/*.h) +file(GLOB_RECURSE GEN_SRC gen/*.cpp gen/abi/*.cpp gen/dcompute/*.cpp) +file(GLOB_RECURSE GEN_HDR gen/*.h gen/abi/*.h gen/dcompute/*.h) file(GLOB_RECURSE GEN_SRC_D gen/*.d) file(GLOB_RECURSE IR_SRC ir/*.cpp) file(GLOB_RECURSE IR_HDR ir/*.h) diff --git a/gen/dcompute/targetVulkan.cpp b/gen/dcompute/targetVulkan.cpp index 64e2bfcc70c..4a11aead02f 100644 --- a/gen/dcompute/targetVulkan.cpp +++ b/gen/dcompute/targetVulkan.cpp @@ -7,6 +7,8 @@ // See the LICENSE file for details. //===----------------------------------------------------------------------===// +#include "llvm/Config/llvm-config.h" + #if LDC_LLVM_SUPPORTED_TARGET_SPIRV && LLVM_VERSION_MAJOR >= 23 #include "dmd/id.h" #include "dmd/identifier.h" @@ -80,8 +82,10 @@ class TargetVulkan : public DComputeTarget { llvm::FunctionType *tf = llf->getFunctionType(); for (unsigned int i = 0; i < tf->getNumParams(); i++) { llvm::Type *t = tf->getParamType(i); - if (t->isPointerTy()) - t = getI64Type(); // FIXME: 32 bit pointers on 32 but systems? + if (t->isPointerTy()){ + unsigned ptrSize = _ir->module.getDataLayout().getPointerSizeInBits(); + t = (ptrSize == 32)?getI32Type():getI64Type(); + } args[i] = t; } From e9d51acea5ffe7389a507b9ec77374c8f7d3c1ed Mon Sep 17 00:00:00 2001 From: Pham Quang Ha Date: Sun, 24 May 2026 13:03:00 +0700 Subject: [PATCH 4/7] remove whitespace noise diff --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd9838e2a56..b33125b7367 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1075,4 +1075,3 @@ install(FILES ${GCCBUILTINS} DESTINATION ${INCLUDE_INSTALL_DIR}/ldc) include (CMakeCPack.cmake) include (CPack) - \ No newline at end of file From 6f9d5f4a64c9bdefeea60021a700b069b4a59da1 Mon Sep 17 00:00:00 2001 From: Pham Quang Ha Date: Sun, 24 May 2026 13:25:36 +0700 Subject: [PATCH 5/7] modify CMakeLists.txt --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b33125b7367..97bed18c12f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ include(BuildDExecutable) find_package(LLVM 18.0 REQUIRED all-targets analysis asmparser asmprinter bitreader bitwriter codegen core - debuginfodwarf debuginfomsf debuginfopdb demangle frontendhlsl + debuginfodwarf debuginfomsf debuginfopdb demangle instcombine ipo instrumentation irreader libdriver linker lto mc mcdisassembler mcparser objcarcopts object option profiledata scalaropts selectiondag support tablegen target transformutils vectorize @@ -150,7 +150,9 @@ if(MSVC) endif() endif() - append("-L/NODEFAULTLIB:libucrt -L/NODEFAULTLIB:libcmt -L/NODEFAULTLIB:libvcruntime -Lmsvcrt.lib -Lucrt.lib -Lvcruntime.lib -Llegacy_stdio_definitions.lib" DFLAGS_BASE) + if(${D_COMPILER_ID} STREQUAL "DigitalMars" AND (MSVC_VERSION GREATER 1800)) # VS 2015+ + append("-Llegacy_stdio_definitions.lib" DFLAGS_BASE) + endif() set(llvm_ob_flag) string(REGEX MATCH "/Ob[0-2]" llvm_ob_flag "${LLVM_CXXFLAGS}") From f9b01c3f3ba6bf3ff6cdc1a7482c11bf19417091 Mon Sep 17 00:00:00 2001 From: Pham Quang Ha Date: Sun, 24 May 2026 16:10:45 +0700 Subject: [PATCH 6/7] fix `.` --- gen/llvmhelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index b932dbba154..3243ecedf5c 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1365,7 +1365,7 @@ void printLabelName(std::ostream &target, const char *func_mangle, // note: quotes needed for Unicode target << '"' #if LLVM_VERSION_MAJOR >= 23 - << gTargetMachine->getMCAsmInfo()->getPrivateLabelPrefix().str() + << gTargetMachine->getMCAsmInfo().getPrivateLabelPrefix().str() #else << gTargetMachine->getMCAsmInfo()->getPrivateGlobalPrefix().str() #endif From 91295190b41a931a97cbbc2b3b1034c69f9f0a8d Mon Sep 17 00:00:00 2001 From: Pham Quang Ha Date: Tue, 26 May 2026 20:53:54 +0700 Subject: [PATCH 7/7] Refactor targetVulkan.cpp to improve pointer handling and streamline intrinsic calls --- gen/dcompute/target.cpp | 4 +++- gen/dcompute/targetVulkan.cpp | 15 +++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/gen/dcompute/target.cpp b/gen/dcompute/target.cpp index 65c6f027c2e..e43588cce81 100644 --- a/gen/dcompute/target.cpp +++ b/gen/dcompute/target.cpp @@ -52,7 +52,9 @@ void DComputeTarget::emit(Module *m) { void DComputeTarget::writeModule() { addMetadata(); - + gABI = abi; + gIR = _ir; + gTargetMachine = targetMachine; std::string filename; llvm::raw_string_ostream os(filename); const bool is64 = global.params.targetTriple->isArch64Bit(); diff --git a/gen/dcompute/targetVulkan.cpp b/gen/dcompute/targetVulkan.cpp index 4a11aead02f..344be6caad9 100644 --- a/gen/dcompute/targetVulkan.cpp +++ b/gen/dcompute/targetVulkan.cpp @@ -149,10 +149,10 @@ class TargetVulkan : public DComputeTarget { // FIXME: call should have `notnull` attribute on pointer? auto *handle = buildIntrinsicCall(builder, "handle","llvm.spv.resource.handlefrombinding", {targetType}, - {i32zero, i32zero, i32one, i32zero, i1false, _ir->getCachedStringLiteral(name.str(), 0) }); + {i32zero, i32zero, i32one, i32zero, _ir->getCachedStringLiteral(name.str(), 0) }); auto *p11 = llvm::PointerType::get(ctx, 11); auto *pointer = buildIntrinsicCall(builder, "pointer", "llvm.spv.resource.getpointer", - {p11, targetType}, {handle, i32one}); + {p11, targetType, i32zero->getType()}, {handle, i32zero}); llvm::FunctionType *tf = llf->getFunctionType(); IF_LOG { Logger::cout() << "load pointer: " << *pointer << std::endl; @@ -163,13 +163,12 @@ class TargetVulkan : public DComputeTarget { LOG_SCOPE llvm::SmallVector args(tf->getNumParams()); - auto *arg = builder.CreateAlignedLoad(argType, pointer, _ir->module.getDataLayout().getABITypeAlign(argType), false); - IF_LOG { - // Logger::cout() << "load elements from " << *arg << std::endl; - // Logger::cout() << "of type " << *argType << std::endl; - } for (unsigned int i = 0; i < tf->getNumParams(); i++) { - args[i] = builder.CreateExtractValue(arg, {i}); + llvm::Value *gep = builder.CreateStructGEP(argType, pointer, i); + llvm::Type *fieldTy = argType->getStructElementType(i); + + args[i] = builder.CreateAlignedLoad(fieldTy, gep, _ir->module.getDataLayout().getABITypeAlign(fieldTy), false); + llvm::Type *t = tf->getParamType(i); if (t->isPointerTy()) args[i] = builder.CreateIntToPtr(args[i],t);