diff --git a/level_zero/core/source/module/module_imp.cpp b/level_zero/core/source/module/module_imp.cpp index 82f4119b1a..91e7d205de 100644 --- a/level_zero/core/source/module/module_imp.cpp +++ b/level_zero/core/source/module/module_imp.cpp @@ -882,7 +882,12 @@ bool ModuleImp::linkBinary() { return LinkingStatus::LinkedPartially == linkStatus; } else if (type != ModuleType::Builtin) { copyPatchedSegments(isaSegmentsForPatching); + } else { + for (auto &kernelDescriptor : kernelDescriptors) { + kernelDescriptor->kernelAttributes.flags.requiresImplicitArgs = false; + } } + DBG_LOG(PrintRelocations, NEO::constructRelocationsDebugMessage(this->symbols)); isFullyLinked = true; for (auto kernelId = 0u; kernelId < kernelImmDatas.size(); kernelId++) { diff --git a/level_zero/core/test/unit_tests/mocks/mock_module.h b/level_zero/core/test/unit_tests/mocks/mock_module.h index 0bda6edffc..af3f3832d6 100644 --- a/level_zero/core/test/unit_tests/mocks/mock_module.h +++ b/level_zero/core/test/unit_tests/mocks/mock_module.h @@ -28,6 +28,7 @@ struct WhiteBox<::L0::Module> : public ::L0::ModuleImp { using BaseClass::importedSymbolAllocations; using BaseClass::isFullyLinked; using BaseClass::kernelImmDatas; + using BaseClass::maxGroupSize; using BaseClass::symbols; using BaseClass::translationUnit; using BaseClass::type; diff --git a/level_zero/core/test/unit_tests/sources/module/test_module.cpp b/level_zero/core/test/unit_tests/sources/module/test_module.cpp index 33675f99b8..f19246483e 100644 --- a/level_zero/core/test/unit_tests/sources/module/test_module.cpp +++ b/level_zero/core/test/unit_tests/sources/module/test_module.cpp @@ -2868,6 +2868,46 @@ TEST_F(ModuleTests, givenConstDataStringSectionWhenLinkingModuleThenSegmentIsPat EXPECT_EQ(static_cast(stringsAddr), *reinterpret_cast(patchAddr)); } +TEST_F(ModuleTests, givenImplicitArgsRelocationAndStackCallsWhenLinkingBuiltinModuleThenSegmentIsNotPatchedAndImplicitArgsAreNotRequired) { + auto pModule = std::make_unique>(device, nullptr, ModuleType::Builtin); + + pModule->maxGroupSize = 32; + + char data[64]{}; + auto kernelInfo = new KernelInfo(); + kernelInfo->heapInfo.KernelHeapSize = 64; + kernelInfo->heapInfo.pKernelHeap = data; + + std::unique_ptr> kernelImmData{new WhiteBox<::L0::KernelImmutableData>(this->device)}; + kernelImmData->initialize(kernelInfo, device, 0, nullptr, nullptr, true); + + kernelImmData->kernelDescriptor->kernelAttributes.flags.useStackCalls = true; + auto isaCpuPtr = reinterpret_cast(kernelImmData->isaGraphicsAllocation->getUnderlyingBuffer()); + pModule->kernelImmDatas.push_back(std::move(kernelImmData)); + pModule->translationUnit->programInfo.kernelInfos.push_back(kernelInfo); + auto linkerInput = std::make_unique<::WhiteBox>(); + linkerInput->traits.requiresPatchingOfInstructionSegments = true; + linkerInput->textRelocations.push_back({{implicitArgsRelocationSymbolName, 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); + pModule->translationUnit->programInfo.linkerInput = std::move(linkerInput); + + EXPECT_FALSE(kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + auto status = pModule->linkBinary(); + EXPECT_TRUE(status); + EXPECT_FALSE(kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + + ze_kernel_handle_t kernelHandle; + + ze_kernel_desc_t kernelDesc = {}; + kernelDesc.pKernelName = kernelInfo->kernelDescriptor.kernelMetadata.kernelName.c_str(); + + ze_result_t res = pModule->createKernel(&kernelDesc, &kernelHandle); + + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + + EXPECT_EQ(0u, *reinterpret_cast(ptrOffset(isaCpuPtr, 0x8))); + Kernel::fromHandle(kernelHandle)->destroy(); +} + TEST_F(ModuleTests, givenImplicitArgsRelocationAndStackCallsWhenLinkingModuleThenSegmentIsPatchedAndImplicitArgsAreRequired) { auto pModule = std::make_unique(device, nullptr, ModuleType::User);