diff --git a/llvm/test/tools/sycl-post-link/device-requirements/sycl-declared-aspects.ll b/llvm/test/tools/sycl-post-link/device-requirements/sycl-declared-aspects.ll new file mode 100644 index 0000000000000..df377f4740948 --- /dev/null +++ b/llvm/test/tools/sycl-post-link/device-requirements/sycl-declared-aspects.ll @@ -0,0 +1,66 @@ +; RUN: sycl-post-link -split=auto %s -o %t.files.table +; RUN: FileCheck %s -input-file=%t.files_0.prop --check-prefix CHECK-AUTO + +; RUN: sycl-post-link -split=kernel %s -o %t.files.table +; RUN: FileCheck %s -input-file=%t.files_0.prop --check-prefix CHECK-KERNEL-0 +; RUN: FileCheck %s -input-file=%t.files_1.prop --check-prefix CHECK-KERNEL-1 +; RUN: FileCheck %s -input-file=%t.files_2.prop --check-prefix CHECK-KERNEL-2 + +; CHECK-AUTO: aspects=2|gBAAAAAAAAQBAAAAGAAAAkAAAAA +; CHECK-KERNEL-0: aspects=2|gBAAAAAAAAQBAAAAGAAAAkAAAAA +; CHECK-KERNEL-1: aspects=2|ABAAAAAAAAQBAAAAGAAAAA +; CHECK-KERNEL-2: aspects=2|gAAAAAAAAAQBAAAA + +source_filename = "source.cpp" +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir64-unknown-unknown" + +$kernel1 = comdat any + +$kernel2 = comdat any + +$kernel3 = comdat any + +define weak_odr dso_local spir_kernel void @kernel1() #0 { +entry: + call spir_func void @_Z3foov() + ret void +} + +define dso_local spir_func void @_Z3foov() !sycl_declared_aspects !4 { +entry: + ret void +} + +define weak_odr dso_local spir_kernel void @kernel2() #0 { +entry: + call spir_func void @_Z3barv() + ret void +} + +define dso_local spir_func void @_Z3barv() !sycl_declared_aspects !5 { +entry: + ret void +} + +define weak_odr dso_local spir_kernel void @kernel3() #0 { +entry: + call spir_func void @_Z3bazv() + ret void +} + +define dso_local spir_func void @_Z3bazv() !sycl_declared_aspects !6 { +entry: + ret void +} + +attributes #0 = { "sycl-module-id"="source.cpp" } + +!sycl_aspects = !{!1, !2, !3} + +!1 = !{!"fp16", i32 5} +!2 = !{!"fp64", i32 6} +!3 = !{!"image", i32 9} +!4 = !{i32 5} +!5 = !{i32 5, i32 6} +!6 = !{i32 5, i32 6, i32 9} diff --git a/llvm/tools/sycl-post-link/SYCLDeviceRequirements.cpp b/llvm/tools/sycl-post-link/SYCLDeviceRequirements.cpp index c388456b04805..137797b49b613 100644 --- a/llvm/tools/sycl-post-link/SYCLDeviceRequirements.cpp +++ b/llvm/tools/sycl-post-link/SYCLDeviceRequirements.cpp @@ -18,32 +18,31 @@ using namespace llvm; void llvm::getSYCLDeviceRequirements( const Module &M, std::map> &Requirements) { - auto ExtractIntegerFromMDNodeOperand = [=](const MDNode *N, - unsigned OpNo) -> unsigned { - Constant *C = - cast(N->getOperand(OpNo).get())->getValue(); - return static_cast(C->getUniqueInteger().getZExtValue()); + std::set Aspects; + auto FindAspectsByMDName = [&](const Function &F, std::string MDName) { + if (const MDNode *MDN = F.getMetadata(MDName)) + for (size_t I = 0, E = MDN->getNumOperands(); I < E; ++I) { + Constant *C = + cast(MDN->getOperand(I).get())->getValue(); + Aspects.insert( + static_cast(C->getUniqueInteger().getZExtValue())); + } }; - // { LLVM-IR metadata name , [SYCL/Device requirements] property name }, see: - // https://github.com/intel/llvm/blob/sycl/sycl/doc/design/OptionalDeviceFeatures.md#create-the-sycldevice-requirements-property-set // Scan the module and if the metadata is present fill the corresponing // property with metadata's aspects - constexpr std::pair ReqdMDs[] = { - {"sycl_used_aspects", "aspects"}, {"sycl_fixed_targets", "fixed_target"}}; + for (const Function &F : M) { + FindAspectsByMDName(F, "sycl_used_aspects"); + FindAspectsByMDName(F, "sycl_declared_aspects"); + } + Requirements["aspects"] = + std::vector(Aspects.begin(), Aspects.end()); - for (const auto &MD : ReqdMDs) { - std::set Aspects; - for (const Function &F : M) { - if (const MDNode *MDN = F.getMetadata(MD.first)) { - for (size_t I = 0, E = MDN->getNumOperands(); I < E; ++I) - Aspects.insert(ExtractIntegerFromMDNodeOperand(MDN, I)); - } - } - // We don't need the "fixed_target" property if it's empty - if (std::string(MD.first) == "sycl_fixed_targets" && Aspects.empty()) - continue; - Requirements[MD.second] = + Aspects.clear(); + for (const Function &F : M) + FindAspectsByMDName(F, "sycl_fixed_targets"); + // We don't need the "fixed_target" property if it's empty + if (!Aspects.empty()) + Requirements["fixed_target"] = std::vector(Aspects.begin(), Aspects.end()); - } }