From f1e1d7ace8910afe37cad2a4834800991ef42b5c Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Thu, 20 Mar 2025 23:32:23 -0700 Subject: [PATCH 01/10] [llvm-exegesis] [AArch64] Resolving Illegal Instruction Error 1) Checking opcodes specifically for LDGM and AUT opcode instruction variants. 2) Gracefully exiting with " : Unsupported opcode: isPointerAuth/isUncheckedAccess" 3) Added corresponding test cases to check exit message. --- .../AArch64/err_skip_illegal_Instruction.s | 8 ++++++++ llvm/tools/llvm-exegesis/lib/Target.cpp | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s diff --git a/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s b/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s new file mode 100644 index 0000000000000..74fe5a7c3a60a --- /dev/null +++ b/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s @@ -0,0 +1,8 @@ +REQUIRES: aarch64-registered-target + +## Check for skipping of illegal instruction errors (AUT and LDGM) +RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --min-instructions=1 --opcode-name=AUTIA --benchmark-phase=assemble-measured-code 2>&1 +CHECK: AUTIA: Unsupported opcode: isPointerAuth/isUncheckedAccess + +RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --min-instructions=1 --opcode-name=LDGM --benchmark-phase=assemble-measured-code 2>&1 +CHECK: LDGM: Unsupported opcode: isPointerAuth/isUncheckedAccess \ No newline at end of file diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index 68d19514bedb2..245d1db5d21e8 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -35,6 +35,14 @@ const ExegesisTarget *ExegesisTarget::lookup(Triple TT) { return nullptr; } +static bool isPointerAuthOpcode(unsigned Opcode) { + return (Opcode >= 1648 && Opcode <= 1667); // AUT instruction class range +} + +static bool isUncheckedAccessOpcode(unsigned Opcode) { + return Opcode == 4694; // LDGM instruction +} + const char * ExegesisTarget::getIgnoredOpcodeReasonOrNull(const LLVMState &State, unsigned Opcode) const { @@ -45,6 +53,8 @@ ExegesisTarget::getIgnoredOpcodeReasonOrNull(const LLVMState &State, return "Unsupported opcode: isBranch/isIndirectBranch"; if (InstrDesc.isCall() || InstrDesc.isReturn()) return "Unsupported opcode: isCall/isReturn"; + if (isPointerAuthOpcode(Opcode) || isUncheckedAccessOpcode(Opcode)) + return "Unsupported opcode: isPointerAuth/isUncheckedAccess"; return nullptr; } From 5039c2b1e1c63c4900b113bf6db662303faf7f53 Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Mon, 24 Mar 2025 02:29:41 -0700 Subject: [PATCH 02/10] [llvm-exegesis] [AArch64] Use enum values for opcode validation - Replace hardcoded opcode ranges with AArch64::* enum values for pointer auth and unchecked access instructions. - Add required AArch64 headers and update tests. - Style changes for corresponding testcases. --- .../AArch64/err_skip_illegal_Instruction.s | 12 +++---- llvm/tools/llvm-exegesis/lib/CMakeLists.txt | 4 +++ llvm/tools/llvm-exegesis/lib/Target.cpp | 31 +++++++++++++++++-- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s b/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s index 74fe5a7c3a60a..3e95bf9a376c7 100644 --- a/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s +++ b/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s @@ -1,8 +1,8 @@ -REQUIRES: aarch64-registered-target +# REQUIRES: aarch64-registered-target -## Check for skipping of illegal instruction errors (AUT and LDGM) -RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --min-instructions=1 --opcode-name=AUTIA --benchmark-phase=assemble-measured-code 2>&1 -CHECK: AUTIA: Unsupported opcode: isPointerAuth/isUncheckedAccess +# Check for skipping of illegal instruction errors (AUT and LDGM) +# RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --opcode-name=AUTIA --benchmark-phase=assemble-measured-code 2>&1 +# CHECK: AUTIA: Unsupported opcode: isPointerAuth/isUncheckedAccess -RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --min-instructions=1 --opcode-name=LDGM --benchmark-phase=assemble-measured-code 2>&1 -CHECK: LDGM: Unsupported opcode: isPointerAuth/isUncheckedAccess \ No newline at end of file +# RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --opcode-name=LDGM --benchmark-phase=assemble-measured-code 2>&1 +# CHECK: LDGM: Unsupported opcode: isPointerAuth/isUncheckedAccess diff --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt index d95c37ff5426b..2de073eda3810 100644 --- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt +++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt @@ -1,3 +1,7 @@ +include_directories( + ${LLVM_MAIN_SRC_DIR}/lib/Target/AArch64 + ${LLVM_BINARY_DIR}/lib/Target/AArch64 + ) set(LLVM_EXEGESIS_TARGETS) if (LLVM_TARGETS_TO_BUILD MATCHES "X86") diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index 245d1db5d21e8..b6a98ec5aa31f 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -15,6 +15,8 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/Error.h" #include "llvm/TargetParser/SubtargetFeature.h" +#include "AArch64.h" +#include "AArch64RegisterInfo.h" namespace llvm { namespace exegesis { @@ -36,12 +38,35 @@ const ExegesisTarget *ExegesisTarget::lookup(Triple TT) { } static bool isPointerAuthOpcode(unsigned Opcode) { - return (Opcode >= 1648 && Opcode <= 1667); // AUT instruction class range + switch (Opcode) { + case AArch64::AUTDA: + case AArch64::AUTDB: + case AArch64::AUTDZA: + case AArch64::AUTDZB: + case AArch64::AUTIA: + case AArch64::AUTIA1716: + case AArch64::AUTIASP: + case AArch64::AUTIAZ: + case AArch64::AUTIB: + case AArch64::AUTIB1716: + case AArch64::AUTIBSP: + case AArch64::AUTIBZ: + case AArch64::AUTIZA: + case AArch64::AUTIZB: + return true; + default: + return false; + } } static bool isUncheckedAccessOpcode(unsigned Opcode) { - return Opcode == 4694; // LDGM instruction -} + switch (Opcode) { + case AArch64::LDGM: + return true; + default: + return false; + } + } const char * ExegesisTarget::getIgnoredOpcodeReasonOrNull(const LLVMState &State, From 6b81e65c64a3946274c642a46906b6cad54e2d8a Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Wed, 26 Mar 2025 07:03:08 -0700 Subject: [PATCH 03/10] [llvm-exegesis][AArch64] Disable pauth and ldgm as unsupported instructions. 1) Change location of isPointerAuth and isLoadTagMultiple function across file for correct implementation 2) Style nits changes in test cases. --- .../AArch64/err_skip_illegal_Instruction.s | 8 --- .../AArch64/skip_unsupported_instructions.s | 8 +++ .../llvm-exegesis/lib/AArch64/Target.cpp | 38 +++++++++++++ llvm/tools/llvm-exegesis/lib/CMakeLists.txt | 4 -- llvm/tools/llvm-exegesis/lib/Target.cpp | 57 ++++++------------- llvm/tools/llvm-exegesis/lib/Target.h | 3 + 6 files changed, 65 insertions(+), 53 deletions(-) delete mode 100644 llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s create mode 100644 llvm/test/tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s diff --git a/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s b/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s deleted file mode 100644 index 3e95bf9a376c7..0000000000000 --- a/llvm/test/tools/llvm-exegesis/AArch64/err_skip_illegal_Instruction.s +++ /dev/null @@ -1,8 +0,0 @@ -# REQUIRES: aarch64-registered-target - -# Check for skipping of illegal instruction errors (AUT and LDGM) -# RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --opcode-name=AUTIA --benchmark-phase=assemble-measured-code 2>&1 -# CHECK: AUTIA: Unsupported opcode: isPointerAuth/isUncheckedAccess - -# RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --opcode-name=LDGM --benchmark-phase=assemble-measured-code 2>&1 -# CHECK: LDGM: Unsupported opcode: isPointerAuth/isUncheckedAccess diff --git a/llvm/test/tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s b/llvm/test/tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s new file mode 100644 index 0000000000000..df92cb7430980 --- /dev/null +++ b/llvm/test/tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s @@ -0,0 +1,8 @@ +# REQUIRES: aarch64-registered-target + +# Check for skipping of illegal instruction errors (AUT and LDGM) +# RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --opcode-name=AUTIA --benchmark-phase=assemble-measured-code 2>&1 | FileCheck %s --check-prefix=CHECK-AUTIA +# CHECK-AUTIA: AUTIA: Unsupported opcode: isPointerAuth + +# RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --opcode-name=LDGM --benchmark-phase=assemble-measured-code 2>&1 | FileCheck %s --check-prefix=CHECK-LDGM +# CHECK-LDGM: LDGM: Unsupported opcode: load tag multiple diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp index bf2b053003ce3..f491f3652c12d 100644 --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -147,5 +147,43 @@ void InitializeAArch64ExegesisTarget() { ExegesisTarget::registerTarget(getTheExegesisAArch64Target()); } +bool isPointerAuth(unsigned Opcode) { + switch (Opcode) { + default: + return false; + + // FIXME: Pointer Authentication instructions. + // We would like to measure these instructions, but they can behave differently on + // different platforms, and maybe the snippets need to look different for these instructions, + // so let's disable this for now. + case AArch64::AUTDA: + case AArch64::AUTDB: + case AArch64::AUTDZA: + case AArch64::AUTDZB: + case AArch64::AUTIA: + case AArch64::AUTIA1716: + case AArch64::AUTIASP: + case AArch64::AUTIAZ: + case AArch64::AUTIB: + case AArch64::AUTIB1716: + case AArch64::AUTIBSP: + case AArch64::AUTIBZ: + case AArch64::AUTIZA: + case AArch64::AUTIZB: + return true; + } +} + +bool isLoadTagMultiple(unsigned Opcode) { + switch (Opcode) { + default: + return false; + + // Load tag multiple instruction + case AArch64::LDGM: + return true; + } +} + } // namespace exegesis } // namespace llvm diff --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt index 2de073eda3810..d95c37ff5426b 100644 --- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt +++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt @@ -1,7 +1,3 @@ -include_directories( - ${LLVM_MAIN_SRC_DIR}/lib/Target/AArch64 - ${LLVM_BINARY_DIR}/lib/Target/AArch64 - ) set(LLVM_EXEGESIS_TARGETS) if (LLVM_TARGETS_TO_BUILD MATCHES "X86") diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index b6a98ec5aa31f..01899a1a67dfe 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -15,8 +15,6 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/Error.h" #include "llvm/TargetParser/SubtargetFeature.h" -#include "AArch64.h" -#include "AArch64RegisterInfo.h" namespace llvm { namespace exegesis { @@ -37,49 +35,26 @@ const ExegesisTarget *ExegesisTarget::lookup(Triple TT) { return nullptr; } -static bool isPointerAuthOpcode(unsigned Opcode) { - switch (Opcode) { - case AArch64::AUTDA: - case AArch64::AUTDB: - case AArch64::AUTDZA: - case AArch64::AUTDZB: - case AArch64::AUTIA: - case AArch64::AUTIA1716: - case AArch64::AUTIASP: - case AArch64::AUTIAZ: - case AArch64::AUTIB: - case AArch64::AUTIB1716: - case AArch64::AUTIBSP: - case AArch64::AUTIBZ: - case AArch64::AUTIZA: - case AArch64::AUTIZB: - return true; - default: - return false; - } -} - -static bool isUncheckedAccessOpcode(unsigned Opcode) { - switch (Opcode) { - case AArch64::LDGM: - return true; - default: - return false; - } - } - const char * ExegesisTarget::getIgnoredOpcodeReasonOrNull(const LLVMState &State, unsigned Opcode) const { const MCInstrDesc &InstrDesc = State.getIC().getInstr(Opcode).Description; - if (InstrDesc.isPseudo() || InstrDesc.usesCustomInsertionHook()) - return "Unsupported opcode: isPseudo/usesCustomInserter"; - if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch()) - return "Unsupported opcode: isBranch/isIndirectBranch"; - if (InstrDesc.isCall() || InstrDesc.isReturn()) - return "Unsupported opcode: isCall/isReturn"; - if (isPointerAuthOpcode(Opcode) || isUncheckedAccessOpcode(Opcode)) - return "Unsupported opcode: isPointerAuth/isUncheckedAccess"; + if (InstrDesc.isPseudo()) + return "Unsupported opcode: isPseudo"; + if ( InstrDesc.usesCustomInsertionHook()) + return "Unsupported opcode: usesCustomInserter"; + if (InstrDesc.isBranch()) + return "Unsupported opcode: isBranch"; + if (InstrDesc.isIndirectBranch()) + return "Unsupported opcode: isIndirectBranch"; + if (InstrDesc.isCall()) + return "Unsupported opcode: isCall"; + if (InstrDesc.isReturn()) + return "Unsupported opcode: isReturn"; + if (isPointerAuth(Opcode)) + return "Unsupported opcode: isPointerAuth"; + if (isLoadTagMultiple(Opcode)) + return "Unsupported opcode: load tag multiple"; return nullptr; } diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 77fbaa6e95412..08f4d74a9c77e 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -335,6 +335,9 @@ class ExegesisTarget { const OpcodeAvailabilityChecker IsOpcodeAvailable; }; +bool isPointerAuth(unsigned Opcode); +bool isLoadTagMultiple(unsigned Opcode); + } // namespace exegesis } // namespace llvm From dade50208122557601d695d44855eabea4a2f366 Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Tue, 1 Apr 2025 08:31:31 -0700 Subject: [PATCH 04/10] [llvm-exegesis][AArch64] Formatting changes --- llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 6 +++--- llvm/tools/llvm-exegesis/lib/Target.h | 3 +-- llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 9 +++------ 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp index f491f3652c12d..f07b26eeee74d 100644 --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -153,9 +153,9 @@ bool isPointerAuth(unsigned Opcode) { return false; // FIXME: Pointer Authentication instructions. - // We would like to measure these instructions, but they can behave differently on - // different platforms, and maybe the snippets need to look different for these instructions, - // so let's disable this for now. + // We would like to measure these instructions, but they can behave + // differently on different platforms, and maybe the snippets need to look + // different for these instructions, so let's disable this for now. case AArch64::AUTDA: case AArch64::AUTDB: case AArch64::AUTDZA: diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 08f4d74a9c77e..53cab14ae8a70 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -268,8 +268,7 @@ class ExegesisTarget { // Creates a snippet generator for the given mode. std::unique_ptr - createSnippetGenerator(Benchmark::ModeE Mode, - const LLVMState &State, + createSnippetGenerator(Benchmark::ModeE Mode, const LLVMState &State, const SnippetGenerator::Options &Opts) const; // Creates a benchmark runner for the given mode. Expected> createBenchmarkRunner( diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp index babcffeb9666a..a99992ebc69a0 100644 --- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -281,7 +281,7 @@ static cl::opt MAttr( static ExitOnError ExitOnErr("llvm-exegesis error: "); // Helper function that logs the error(s) and exits. -template static void ExitWithError(ArgTs &&... Args) { +template static void ExitWithError(ArgTs &&...Args) { ExitOnErr(make_error(std::forward(Args)...)); } @@ -444,8 +444,7 @@ static void runBenchmarkConfigurations( Benchmark &Result = AllResults.front(); // If any of our measurements failed, pretend they all have failed. - if (AllResults.size() > 1 && - any_of(AllResults, [](const Benchmark &R) { + if (AllResults.size() > 1 && any_of(AllResults, [](const Benchmark &R) { return R.Measurements.empty(); })) Result.Measurements.clear(); @@ -505,7 +504,6 @@ void benchmarkMain() { if (!Runner) { ExitWithError("cannot create benchmark runner"); } - const auto Opcodes = getOpcodesOrDie(State); std::vector Configurations; @@ -643,8 +641,7 @@ static void analysisMain() { errorOrToExpected(MemoryBuffer::getFile(BenchmarkFile, /*IsText=*/true))); const auto TriplesAndCpus = ExitOnFileError( - BenchmarkFile, - Benchmark::readTriplesAndCpusFromYamls(*MemoryBuffer)); + BenchmarkFile, Benchmark::readTriplesAndCpusFromYamls(*MemoryBuffer)); if (TriplesAndCpus.empty()) { errs() << "no benchmarks to analyze\n"; return; From b6ce448de4c08a742045f1416d5c8fbc3ad7c434 Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Tue, 1 Apr 2025 08:34:44 -0700 Subject: [PATCH 05/10] [llvm-exegesis] Add Linux PR_PAC_* constants and update opcode handling - Included necessary headers for PR_PAC_* constants and modified the getIgnoredOpcodeReasonOrNull function to disabling pointer authentication. - Adjusted formatting. --- llvm/tools/llvm-exegesis/lib/Target.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index 01899a1a67dfe..3dbf695f19d84 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -16,6 +16,9 @@ #include "llvm/Support/Error.h" #include "llvm/TargetParser/SubtargetFeature.h" +#include // For PR_PAC_* constants +#include + namespace llvm { namespace exegesis { @@ -41,7 +44,7 @@ ExegesisTarget::getIgnoredOpcodeReasonOrNull(const LLVMState &State, const MCInstrDesc &InstrDesc = State.getIC().getInstr(Opcode).Description; if (InstrDesc.isPseudo()) return "Unsupported opcode: isPseudo"; - if ( InstrDesc.usesCustomInsertionHook()) + if (InstrDesc.usesCustomInsertionHook()) return "Unsupported opcode: usesCustomInserter"; if (InstrDesc.isBranch()) return "Unsupported opcode: isBranch"; @@ -52,7 +55,11 @@ ExegesisTarget::getIgnoredOpcodeReasonOrNull(const LLVMState &State, if (InstrDesc.isReturn()) return "Unsupported opcode: isReturn"; if (isPointerAuth(Opcode)) - return "Unsupported opcode: isPointerAuth"; + prctl(PR_PAC_SET_ENABLED_KEYS, + PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | + PR_PAC_APDBKEY, // all keys + 0, // disable all + 0, 0); if (isLoadTagMultiple(Opcode)) return "Unsupported opcode: load tag multiple"; return nullptr; @@ -123,9 +130,8 @@ ExegesisTarget::createBenchmarkRunner( case Benchmark::InverseThroughput: if (BenchmarkPhaseSelector == BenchmarkPhaseSelectorE::Measure && !PfmCounters.CycleCounter) { - const char *ModeName = Mode == Benchmark::Latency - ? "latency" - : "inverse_throughput"; + const char *ModeName = + Mode == Benchmark::Latency ? "latency" : "inverse_throughput"; return make_error( Twine("can't run '") .concat(ModeName) @@ -158,7 +164,8 @@ std::unique_ptr ExegesisTarget::createSerialSnippetGenerator( return std::make_unique(State, Opts); } -std::unique_ptr ExegesisTarget::createParallelSnippetGenerator( +std::unique_ptr +ExegesisTarget::createParallelSnippetGenerator( const LLVMState &State, const SnippetGenerator::Options &Opts) const { return std::make_unique(State, Opts); } From 783f86de978576646369a73d6c01576832659041 Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Tue, 1 Apr 2025 09:24:23 -0700 Subject: [PATCH 06/10] [llvm-exegesis][AArch64] Updated the testcase for AUT instruction class. --- .../tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s b/llvm/test/tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s index df92cb7430980..acefbce2e94c5 100644 --- a/llvm/test/tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s +++ b/llvm/test/tools/llvm-exegesis/AArch64/skip_unsupported_instructions.s @@ -2,7 +2,7 @@ # Check for skipping of illegal instruction errors (AUT and LDGM) # RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --opcode-name=AUTIA --benchmark-phase=assemble-measured-code 2>&1 | FileCheck %s --check-prefix=CHECK-AUTIA -# CHECK-AUTIA: AUTIA: Unsupported opcode: isPointerAuth +# CHECK-AUTIA-NOT: snippet crashed while running: Illegal instruction # RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --opcode-name=LDGM --benchmark-phase=assemble-measured-code 2>&1 | FileCheck %s --check-prefix=CHECK-LDGM # CHECK-LDGM: LDGM: Unsupported opcode: load tag multiple From 70eb3bf1071dd22e4ee2590f1bc057b285f34db4 Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Wed, 2 Apr 2025 23:19:48 -0700 Subject: [PATCH 07/10] [llvm-exegesis][AArch64] Refactor opcode handling for pointer authentication and load tag multiple - Moved isPointerAuth and isLoadTagMultiple functions to AArch64/Target.cpp for better organization. - Updated getIgnoredOpcodeReasonOrNull to handle pointer authentication and load tag multiple opcodes correctly. - Removed redundant definitions from Target.cpp and Target.h. --- .../llvm-exegesis/lib/AArch64/Target.cpp | 101 +++++++++++------- llvm/tools/llvm-exegesis/lib/Target.cpp | 11 -- llvm/tools/llvm-exegesis/lib/Target.h | 3 - 3 files changed, 63 insertions(+), 52 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp index f07b26eeee74d..78ec1a244c8b1 100644 --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -9,12 +9,54 @@ #include "AArch64.h" #include "AArch64RegisterInfo.h" +#include // For PR_PAC_* constants +#include + #define GET_AVAILABLE_OPCODE_CHECKER #include "AArch64GenInstrInfo.inc" namespace llvm { namespace exegesis { +bool isPointerAuth(unsigned Opcode) { + switch (Opcode) { + default: + return false; + + // FIXME: Pointer Authentication instructions. + // We would like to measure these instructions, but they can behave + // differently on different platforms, and maybe the snippets need to look + // different for these instructions, so we disable PAC keys via prctl to allow + // measuring them without authentication failures. + case AArch64::AUTDA: + case AArch64::AUTDB: + case AArch64::AUTDZA: + case AArch64::AUTDZB: + case AArch64::AUTIA: + case AArch64::AUTIA1716: + case AArch64::AUTIASP: + case AArch64::AUTIAZ: + case AArch64::AUTIB: + case AArch64::AUTIB1716: + case AArch64::AUTIBSP: + case AArch64::AUTIBZ: + case AArch64::AUTIZA: + case AArch64::AUTIZB: + return true; + } +} + +bool isLoadTagMultiple(unsigned Opcode) { + switch (Opcode) { + default: + return false; + + // Load tag multiple instruction + case AArch64::LDGM: + return true; + } +} + static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) { switch (RegBitWidth) { case 32: @@ -134,6 +176,27 @@ class ExegesisAArch64Target : public ExegesisTarget { // Function return is a pseudo-instruction that needs to be expanded PM.add(createAArch64ExpandPseudoPass()); } + + const char *getIgnoredOpcodeReasonOrNull(const LLVMState &State, + unsigned Opcode) const override { + if (const char *Reason = + ExegesisTarget::getIgnoredOpcodeReasonOrNull(State, Opcode)) + return Reason; + + if (isPointerAuth(Opcode)) { + // Disable all PAC keys + prctl(PR_PAC_SET_ENABLED_KEYS, + PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | + PR_PAC_APDBKEY, // all keys + 0, // disable all + 0, 0); + } + + if (isLoadTagMultiple(Opcode)) + return "Unsupported opcode: load tag multiple"; + + return nullptr; + } }; } // namespace @@ -147,43 +210,5 @@ void InitializeAArch64ExegesisTarget() { ExegesisTarget::registerTarget(getTheExegesisAArch64Target()); } -bool isPointerAuth(unsigned Opcode) { - switch (Opcode) { - default: - return false; - - // FIXME: Pointer Authentication instructions. - // We would like to measure these instructions, but they can behave - // differently on different platforms, and maybe the snippets need to look - // different for these instructions, so let's disable this for now. - case AArch64::AUTDA: - case AArch64::AUTDB: - case AArch64::AUTDZA: - case AArch64::AUTDZB: - case AArch64::AUTIA: - case AArch64::AUTIA1716: - case AArch64::AUTIASP: - case AArch64::AUTIAZ: - case AArch64::AUTIB: - case AArch64::AUTIB1716: - case AArch64::AUTIBSP: - case AArch64::AUTIBZ: - case AArch64::AUTIZA: - case AArch64::AUTIZB: - return true; - } -} - -bool isLoadTagMultiple(unsigned Opcode) { - switch (Opcode) { - default: - return false; - - // Load tag multiple instruction - case AArch64::LDGM: - return true; - } -} - } // namespace exegesis } // namespace llvm diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index 3dbf695f19d84..2bc6dc0caa65d 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -16,9 +16,6 @@ #include "llvm/Support/Error.h" #include "llvm/TargetParser/SubtargetFeature.h" -#include // For PR_PAC_* constants -#include - namespace llvm { namespace exegesis { @@ -54,14 +51,6 @@ ExegesisTarget::getIgnoredOpcodeReasonOrNull(const LLVMState &State, return "Unsupported opcode: isCall"; if (InstrDesc.isReturn()) return "Unsupported opcode: isReturn"; - if (isPointerAuth(Opcode)) - prctl(PR_PAC_SET_ENABLED_KEYS, - PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | - PR_PAC_APDBKEY, // all keys - 0, // disable all - 0, 0); - if (isLoadTagMultiple(Opcode)) - return "Unsupported opcode: load tag multiple"; return nullptr; } diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 53cab14ae8a70..5b5acd968f840 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -334,9 +334,6 @@ class ExegesisTarget { const OpcodeAvailabilityChecker IsOpcodeAvailable; }; -bool isPointerAuth(unsigned Opcode); -bool isLoadTagMultiple(unsigned Opcode); - } // namespace exegesis } // namespace llvm From a1fedb4029a97f57b33b2ce7d9621b9c3b7a1d8c Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Thu, 3 Apr 2025 07:15:41 -0700 Subject: [PATCH 08/10] [llvm-exegesis][AArch64] Enhance pointer authentication handling for Linux - Added platform-specific handling for pointer authentication instructions, enabling the disabling of PAC keys on Linux. - Ensured that unsupported opcodes return an appropriate message on non-Linux platforms. --- .../llvm-exegesis/lib/AArch64/Target.cpp | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp index 78ec1a244c8b1..1aca258603590 100644 --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -9,8 +9,10 @@ #include "AArch64.h" #include "AArch64RegisterInfo.h" +#ifdef __linux__ #include // For PR_PAC_* constants #include +#endif #define GET_AVAILABLE_OPCODE_CHECKER #include "AArch64GenInstrInfo.inc" @@ -26,8 +28,10 @@ bool isPointerAuth(unsigned Opcode) { // FIXME: Pointer Authentication instructions. // We would like to measure these instructions, but they can behave // differently on different platforms, and maybe the snippets need to look - // different for these instructions, so we disable PAC keys via prctl to allow - // measuring them without authentication failures. + // different for these instructions, + // Platform-specific handling: On Linux, we disable authentication, may + // interfere with measurements. On non-Linux platforms, disable opcodes for + // now. case AArch64::AUTDA: case AArch64::AUTDB: case AArch64::AUTDZA: @@ -184,12 +188,20 @@ class ExegesisAArch64Target : public ExegesisTarget { return Reason; if (isPointerAuth(Opcode)) { - // Disable all PAC keys - prctl(PR_PAC_SET_ENABLED_KEYS, - PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | - PR_PAC_APDBKEY, // all keys - 0, // disable all - 0, 0); +#ifdef __linux__ + // Disable all PAC keys. Note that while we expect the measurements to + // be the same with PAC keys disabled, they could potentially be lower + // since authentication checks are bypassed. + if (prctl(PR_PAC_SET_ENABLED_KEYS, + PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | + PR_PAC_APDBKEY, // all keys + 0, // disable all + 0, 0) < 0) { + return "Failed to disable PAC keys"; + } +#else + return "Unsupported opcode: isPointerAuth"; +#endif } if (isLoadTagMultiple(Opcode)) From 06fbe30cbeb4f5b4a5b396ce35c019f518d18fbb Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Thu, 3 Apr 2025 21:30:00 -0700 Subject: [PATCH 09/10] Revert "[llvm-exegesis][AArch64] Formatting changes" This reverts commit dade50208122557601d695d44855eabea4a2f366. --- llvm/tools/llvm-exegesis/lib/Target.h | 3 ++- llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 5b5acd968f840..77fbaa6e95412 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -268,7 +268,8 @@ class ExegesisTarget { // Creates a snippet generator for the given mode. std::unique_ptr - createSnippetGenerator(Benchmark::ModeE Mode, const LLVMState &State, + createSnippetGenerator(Benchmark::ModeE Mode, + const LLVMState &State, const SnippetGenerator::Options &Opts) const; // Creates a benchmark runner for the given mode. Expected> createBenchmarkRunner( diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp index a99992ebc69a0..babcffeb9666a 100644 --- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -281,7 +281,7 @@ static cl::opt MAttr( static ExitOnError ExitOnErr("llvm-exegesis error: "); // Helper function that logs the error(s) and exits. -template static void ExitWithError(ArgTs &&...Args) { +template static void ExitWithError(ArgTs &&... Args) { ExitOnErr(make_error(std::forward(Args)...)); } @@ -444,7 +444,8 @@ static void runBenchmarkConfigurations( Benchmark &Result = AllResults.front(); // If any of our measurements failed, pretend they all have failed. - if (AllResults.size() > 1 && any_of(AllResults, [](const Benchmark &R) { + if (AllResults.size() > 1 && + any_of(AllResults, [](const Benchmark &R) { return R.Measurements.empty(); })) Result.Measurements.clear(); @@ -504,6 +505,7 @@ void benchmarkMain() { if (!Runner) { ExitWithError("cannot create benchmark runner"); } + const auto Opcodes = getOpcodesOrDie(State); std::vector Configurations; @@ -641,7 +643,8 @@ static void analysisMain() { errorOrToExpected(MemoryBuffer::getFile(BenchmarkFile, /*IsText=*/true))); const auto TriplesAndCpus = ExitOnFileError( - BenchmarkFile, Benchmark::readTriplesAndCpusFromYamls(*MemoryBuffer)); + BenchmarkFile, + Benchmark::readTriplesAndCpusFromYamls(*MemoryBuffer)); if (TriplesAndCpus.empty()) { errs() << "no benchmarks to analyze\n"; return; From 3af87a05c15ea9ff582e5b5f3e897d5326ebe24d Mon Sep 17 00:00:00 2001 From: lakshayk-nv Date: Mon, 7 Apr 2025 02:48:45 -0700 Subject: [PATCH 10/10] [llvm-exegesis][AArch64] Revert back unnecessary unfolded error and formatting changes. --- llvm/tools/llvm-exegesis/lib/Target.cpp | 26 ++++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index 2bc6dc0caa65d..68d19514bedb2 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -39,18 +39,12 @@ const char * ExegesisTarget::getIgnoredOpcodeReasonOrNull(const LLVMState &State, unsigned Opcode) const { const MCInstrDesc &InstrDesc = State.getIC().getInstr(Opcode).Description; - if (InstrDesc.isPseudo()) - return "Unsupported opcode: isPseudo"; - if (InstrDesc.usesCustomInsertionHook()) - return "Unsupported opcode: usesCustomInserter"; - if (InstrDesc.isBranch()) - return "Unsupported opcode: isBranch"; - if (InstrDesc.isIndirectBranch()) - return "Unsupported opcode: isIndirectBranch"; - if (InstrDesc.isCall()) - return "Unsupported opcode: isCall"; - if (InstrDesc.isReturn()) - return "Unsupported opcode: isReturn"; + if (InstrDesc.isPseudo() || InstrDesc.usesCustomInsertionHook()) + return "Unsupported opcode: isPseudo/usesCustomInserter"; + if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch()) + return "Unsupported opcode: isBranch/isIndirectBranch"; + if (InstrDesc.isCall() || InstrDesc.isReturn()) + return "Unsupported opcode: isCall/isReturn"; return nullptr; } @@ -119,8 +113,9 @@ ExegesisTarget::createBenchmarkRunner( case Benchmark::InverseThroughput: if (BenchmarkPhaseSelector == BenchmarkPhaseSelectorE::Measure && !PfmCounters.CycleCounter) { - const char *ModeName = - Mode == Benchmark::Latency ? "latency" : "inverse_throughput"; + const char *ModeName = Mode == Benchmark::Latency + ? "latency" + : "inverse_throughput"; return make_error( Twine("can't run '") .concat(ModeName) @@ -153,8 +148,7 @@ std::unique_ptr ExegesisTarget::createSerialSnippetGenerator( return std::make_unique(State, Opts); } -std::unique_ptr -ExegesisTarget::createParallelSnippetGenerator( +std::unique_ptr ExegesisTarget::createParallelSnippetGenerator( const LLVMState &State, const SnippetGenerator::Options &Opts) const { return std::make_unique(State, Opts); }