diff --git a/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp b/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp index 5659a60eb1..15ecf51905 100644 --- a/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp +++ b/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp @@ -10,6 +10,8 @@ #include "shared/source/compiler_interface/intermediate_representations.h" #include "shared/source/compiler_interface/oclc_extensions.h" #include "shared/source/debug_settings/debug_settings_manager.h" +#include "shared/source/device_binary_format/elf/elf_decoder.h" +#include "shared/source/device_binary_format/elf/ocl_elf.h" #include "shared/source/helpers/file_io.h" #include "shared/source/helpers/hw_info.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" @@ -71,6 +73,15 @@ void compilerOutputRemove(const std::string &fileName, const std::string &type) std::remove(getCompilerOutputFileName(fileName, type).c_str()); } +template +bool isAnyIrSectionDefined(const SectionHeaders §ionHeaders) { + const auto isIrSection = [](const auto §ion) { + return section.header && (section.header->type == Elf::SHT_OPENCL_SPIRV || section.header->type == Elf::SHT_OPENCL_LLVM_BINARY); + }; + + return std::any_of(sectionHeaders.begin(), sectionHeaders.end(), isIrSection); +} + TEST_F(MultiCommandTests, WhenBuildingMultiCommandThenSuccessIsReturned) { nameOfFileWithArgs = "test_files/ImAMulitiComandMinimalGoodFile.txt"; std::vector argv = { @@ -389,6 +400,57 @@ TEST_F(OfflineCompilerTests, givenDashGInBiggerOptionStringWhenInitializingThenI EXPECT_THAT(internalOptions, ::testing::Not(::testing::HasSubstr("-cl-kernel-debug-enable"))); } +TEST_F(OfflineCompilerTests, givenExcludeIrArgumentWhenCompilingKernelThenIrShouldBeExcluded) { + + std::vector argv = { + "ocloc", + "-file", + "test_files/copybuffer.cl", + "-exclude_ir", + "-device", + gEnvironment->devicePrefix.c_str()}; + + MockOfflineCompiler mockOfflineCompiler{}; + mockOfflineCompiler.initialize(argv.size(), argv); + + const auto buildResult{mockOfflineCompiler.build()}; + EXPECT_EQ(OfflineCompiler::SUCCESS, buildResult); + + std::string errorReason{}; + std::string warning{}; + + const auto elf{Elf::decodeElf(mockOfflineCompiler.elfBinary, errorReason, warning)}; + ASSERT_TRUE(errorReason.empty()); + ASSERT_TRUE(warning.empty()); + + EXPECT_FALSE(isAnyIrSectionDefined(elf.sectionHeaders)); +} + +TEST_F(OfflineCompilerTests, givenLackOfExcludeIrArgumentWhenCompilingKernelThenIrShouldBeIncluded) { + + std::vector argv = { + "ocloc", + "-file", + "test_files/copybuffer.cl", + "-device", + gEnvironment->devicePrefix.c_str()}; + + MockOfflineCompiler mockOfflineCompiler{}; + mockOfflineCompiler.initialize(argv.size(), argv); + + const auto buildResult{mockOfflineCompiler.build()}; + EXPECT_EQ(OfflineCompiler::SUCCESS, buildResult); + + std::string errorReason{}; + std::string warning{}; + + const auto elf{Elf::decodeElf(mockOfflineCompiler.elfBinary, errorReason, warning)}; + ASSERT_TRUE(errorReason.empty()); + ASSERT_TRUE(warning.empty()); + + EXPECT_TRUE(isAnyIrSectionDefined(elf.sectionHeaders)); +} + TEST_F(OfflineCompilerTests, givenVariousClStdValuesWhenCompilingSourceThenCorrectExtensionsArePassed) { std::string clStdOptionValues[] = {"", "-cl-std=CL1.2", "-cl-std=CL2.0", "-cl-std=CL3.0"}; diff --git a/shared/offline_compiler/source/offline_compiler.cpp b/shared/offline_compiler/source/offline_compiler.cpp index c89eef25b3..7456f9a13c 100644 --- a/shared/offline_compiler/source/offline_compiler.cpp +++ b/shared/offline_compiler/source/offline_compiler.cpp @@ -667,6 +667,8 @@ int OfflineCompiler::parseCommandLine(size_t numArgs, const std::vectorprintf("Invalid option (arg %d): %s\n", argIndex, argv[argIndex].c_str()); retVal = INVALID_COMMAND_LINE; @@ -946,6 +948,8 @@ Usage: ocloc [compile] -file -device [-output Target stepping. Can be decimal or hexadecimal value. + -exclude_ir Excludes IR from the output binary file. + Examples : Compile file to Intel Compute GPU device binary (out = source_file_Gen9core.bin) ocloc -file source_file.cl -device skl @@ -997,7 +1001,7 @@ bool OfflineCompiler::generateElfBinary() { ArrayRef(reinterpret_cast(binary.buildOptions.data()), binary.buildOptions.size())); } - if (binary.intermediateRepresentation.empty() == false) { + if (!binary.intermediateRepresentation.empty() && !excludeIr) { if (isSpirV) { ElfEncoder.appendSection(SHT_OPENCL_SPIRV, SectionNamesOpenCl::spirvObject, binary.intermediateRepresentation); } else { diff --git a/shared/offline_compiler/source/offline_compiler.h b/shared/offline_compiler/source/offline_compiler.h index 3506ebeb3b..9f56f27560 100644 --- a/shared/offline_compiler/source/offline_compiler.h +++ b/shared/offline_compiler/source/offline_compiler.h @@ -139,6 +139,7 @@ class OfflineCompiler { bool forceStatelessToStatefulOptimization = false; bool isSpirV = false; bool showHelp = false; + bool excludeIr = false; std::vector elfBinary; char *genBinary = nullptr;