[llvm] [llvm-exegesis] Debug generated disassembly (PR #142540)
Lakshay Kumar via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 1 01:44:50 PDT 2025
https://github.com/lakshayk-nv updated https://github.com/llvm/llvm-project/pull/142540
>From 3c9421c4185a27e8e6256f41b0e9e8898b08ad41 Mon Sep 17 00:00:00 2001
From: lakshayk-nv <lakshayk at nvidia.com>
Date: Fri, 30 May 2025 03:46:29 -0700
Subject: [PATCH 01/24] [llvm-exegesis] Added Debug flag for print disassembly
using objdump
---
.../llvm-exegesis/lib/BenchmarkRunner.cpp | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index a7771b99e97b1..bc2b0b4750e6a 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -29,6 +29,8 @@
#include <cmath>
#include <memory>
#include <string>
+#include "llvm/Support/Debug.h"
+#define DEBUG_TYPE "exegesis-benchmark-runner"
#ifdef __linux__
#ifdef HAVE_LIBPFM
@@ -709,6 +711,35 @@ std::pair<Error, Benchmark> BenchmarkRunner::runConfiguration(
}
outs() << "Check generated assembly with: /usr/bin/objdump -d "
<< *ObjectFilePath << "\n";
+
+ int StdOutFD, StdErrFD;
+ SmallString<128> StdOutFile, StdErrFile;
+ sys::fs::createTemporaryFile("temp-objdump-out", "txt", StdOutFD, StdOutFile);
+ sys::fs::createTemporaryFile("temp-objdump-err", "txt", StdErrFD, StdErrFile);
+
+ std::vector<std::optional<StringRef>> Redirects = {
+ std::nullopt, // stdin
+ StringRef(StdOutFile), // stdout
+ StringRef(StdErrFile) // stderr
+ };
+
+#ifdef __linux__
+ std::string ErrMsg;
+ int Result = sys::ExecuteAndWait(
+ "/usr/bin/objdump", {"/usr/bin/objdump", "-d", *ObjectFilePath},
+ std::nullopt, Redirects, 0, 0, &ErrMsg);
+ auto StdOutBuf = MemoryBuffer::getFile(StdOutFile);
+ if (StdOutBuf && !(*StdOutBuf)->getBuffer().empty())
+ LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] Generated assembly:\n"
+ << (*StdOutBuf)->getBuffer() << '\n');
+ auto StdErrBuf = MemoryBuffer::getFile(StdErrFile);
+ if (StdErrBuf && !(*StdErrBuf)->getBuffer().empty())
+ LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] stderr:\n"
+ << (*StdErrBuf)->getBuffer() << '\n');
+ if (!ErrMsg.empty())
+ LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] process error: " << ErrMsg << '\n');
+#endif
+ sys::fs::remove(StdOutFile); sys::fs::remove(StdErrFile);
}
if (BenchmarkPhaseSelector < BenchmarkPhaseSelectorE::Measure) {
>From 7d61a14b246ebd6b82fe046d63407a813d65da19 Mon Sep 17 00:00:00 2001
From: lakshayk-nv <lakshayk at nvidia.com>
Date: Mon, 2 Jun 2025 22:53:56 -0700
Subject: [PATCH 02/24] [llvm-exegesis] Formatting changes
---
.../llvm-exegesis/lib/BenchmarkRunner.cpp | 23 +++++++++++--------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index bc2b0b4750e6a..7c2a6c966106a 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -29,7 +30,6 @@
#include <cmath>
#include <memory>
#include <string>
-#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "exegesis-benchmark-runner"
#ifdef __linux__
@@ -712,18 +712,19 @@ std::pair<Error, Benchmark> BenchmarkRunner::runConfiguration(
outs() << "Check generated assembly with: /usr/bin/objdump -d "
<< *ObjectFilePath << "\n";
+#ifdef __linux__
int StdOutFD, StdErrFD;
SmallString<128> StdOutFile, StdErrFile;
- sys::fs::createTemporaryFile("temp-objdump-out", "txt", StdOutFD, StdOutFile);
- sys::fs::createTemporaryFile("temp-objdump-err", "txt", StdErrFD, StdErrFile);
-
+ sys::fs::createTemporaryFile("temp-objdump-out", "txt", StdOutFD,
+ StdOutFile);
+ sys::fs::createTemporaryFile("temp-objdump-err", "txt", StdErrFD,
+ StdErrFile);
std::vector<std::optional<StringRef>> Redirects = {
- std::nullopt, // stdin
- StringRef(StdOutFile), // stdout
- StringRef(StdErrFile) // stderr
+ std::nullopt, // stdin
+ StringRef(StdOutFile), // stdout
+ StringRef(StdErrFile) // stderr
};
-#ifdef __linux__
std::string ErrMsg;
int Result = sys::ExecuteAndWait(
"/usr/bin/objdump", {"/usr/bin/objdump", "-d", *ObjectFilePath},
@@ -737,9 +738,11 @@ std::pair<Error, Benchmark> BenchmarkRunner::runConfiguration(
LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] stderr:\n"
<< (*StdErrBuf)->getBuffer() << '\n');
if (!ErrMsg.empty())
- LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] process error: " << ErrMsg << '\n');
+ LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] process error: " << ErrMsg
+ << '\n');
+ sys::fs::remove(StdOutFile);
+ sys::fs::remove(StdErrFile);
#endif
- sys::fs::remove(StdOutFile); sys::fs::remove(StdErrFile);
}
if (BenchmarkPhaseSelector < BenchmarkPhaseSelectorE::Measure) {
>From e53e3c8813d305edc2e1cdbeebc3dde372458c7f Mon Sep 17 00:00:00 2001
From: lakshayk-nv <lakshayk at nvidia.com>
Date: Mon, 30 Jun 2025 20:57:58 -0700
Subject: [PATCH 03/24] [llvm-exegesis] Debug (print or preview) generated
assembly without external dependency outside llvm project
---
.../llvm-exegesis/lib/BenchmarkRunner.cpp | 128 +++++++++++++-----
llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 4 +-
2 files changed, 97 insertions(+), 35 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 7c2a6c966106a..6e733f59a6b65 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -8,6 +8,7 @@
#include "BenchmarkRunner.h"
#include "Assembler.h"
+#include "DisassemblerHelper.h"
#include "Error.h"
#include "MCInstrDescView.h"
#include "MmapUtils.h"
@@ -18,19 +19,21 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/MC/TargetRegistry.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/SystemZ/zOSSupport.h"
#include <cmath>
#include <memory>
#include <string>
-#define DEBUG_TYPE "exegesis-benchmark-runner"
#ifdef __linux__
#ifdef HAVE_LIBPFM
@@ -657,8 +660,97 @@ BenchmarkRunner::getRunnableConfiguration(
if (Error E = Snippet.takeError())
return std::move(E);
RC.ObjectFile = getObjectFromBuffer(*Snippet);
- }
+ // Print the assembled snippet by disassembling the binary data
+ // Extract the actual function bytes from the object file
+ std::vector<uint8_t> FunctionBytes;
+ if (auto Err = getBenchmarkFunctionBytes(*Snippet, FunctionBytes)) {
+ dbgs() << "Failed to extract function bytes: " << toString(std::move(Err))
+ << "\n";
+ } else {
+ DisassemblerHelper DisHelper(State);
+ ArrayRef<uint8_t> Bytes(FunctionBytes);
+
+ // Decode all instructions first
+ struct InstructionInfo {
+ std::string Text;
+ uint64_t Address;
+ std::string HexBytes;
+ };
+ std::vector<InstructionInfo> Instructions;
+ uint64_t Address = 0;
+
+ while (!Bytes.empty()) {
+ MCInst Inst;
+ uint64_t Size;
+ if (DisHelper.decodeInst(Inst, Size, Bytes)) {
+ // Format instruction text
+ std::string InstStr;
+ raw_string_ostream OS(InstStr);
+ DisHelper.printInst(&Inst, OS);
+
+ // Create hex string for this instruction (big-endian order)
+ std::string HexStr;
+ raw_string_ostream HexOS(HexStr);
+ for (int i = Size - 1; i >= 0; --i) {
+ HexOS << format_hex_no_prefix(Bytes[i], 2);
+ }
+
+ Instructions.push_back({OS.str(), Address, HexOS.str()});
+ Bytes = Bytes.slice(Size);
+ Address += Size;
+ } else {
+ Instructions.push_back({"<decode error>", Address, ""});
+ break;
+ }
+ }
+
+ auto printSnippet = [&](bool Preview, size_t PreviewFirst = 10,
+ size_t PreviewLast = 3) {
+ dbgs() << "```\n";
+ size_t N = Instructions.size();
+ // Print first "PreviewFirst" lines or all if less
+ for (size_t i = 0; i < std::min(size_t(PreviewFirst), N); ++i) {
+ dbgs() << format_hex_no_prefix(Instructions[i].Address, 0) << ":\t"
+ << Instructions[i].HexBytes << Instructions[i].Text << '\n';
+ }
+ if (N > (PreviewFirst + PreviewLast)) {
+ if (Preview) {
+ dbgs() << "...\t(" << (N - PreviewFirst - PreviewLast)
+ << " more instructions)\n";
+ } else {
+ // Print all middle lines
+ for (size_t i = PreviewFirst; i < N - PreviewLast; ++i) {
+ dbgs() << format_hex_no_prefix(Instructions[i].Address, 0)
+ << ":\t" << Instructions[i].HexBytes
+ << Instructions[i].Text << '\n';
+ }
+ }
+ // Print last "PreviewLast" lines
+ for (size_t i = N - PreviewLast; i < N; ++i) {
+ dbgs() << format_hex_no_prefix(Instructions[i].Address, 0) << ":\t"
+ << Instructions[i].HexBytes << Instructions[i].Text << '\n';
+ }
+ }
+ dbgs() << "```\n";
+ };
+
+ // Preview generated assembly snippet
+ {
+#undef DEBUG_TYPE
+#define DEBUG_TYPE "preview-gen-assembly"
+ LLVM_DEBUG(dbgs() << "Generated assembly snippet:\n");
+ LLVM_DEBUG(printSnippet(true));
+#undef DEBUG_TYPE
+#define DEBUG_TYPE "print-gen-assembly"
+ }
+ // Print generated assembly snippet
+ {
+ LLVM_DEBUG(dbgs() << "Generated assembly snippet:\n");
+ LLVM_DEBUG(printSnippet(false));
+ }
+ }
+ }
return std::move(RC);
}
@@ -711,38 +803,6 @@ std::pair<Error, Benchmark> BenchmarkRunner::runConfiguration(
}
outs() << "Check generated assembly with: /usr/bin/objdump -d "
<< *ObjectFilePath << "\n";
-
-#ifdef __linux__
- int StdOutFD, StdErrFD;
- SmallString<128> StdOutFile, StdErrFile;
- sys::fs::createTemporaryFile("temp-objdump-out", "txt", StdOutFD,
- StdOutFile);
- sys::fs::createTemporaryFile("temp-objdump-err", "txt", StdErrFD,
- StdErrFile);
- std::vector<std::optional<StringRef>> Redirects = {
- std::nullopt, // stdin
- StringRef(StdOutFile), // stdout
- StringRef(StdErrFile) // stderr
- };
-
- std::string ErrMsg;
- int Result = sys::ExecuteAndWait(
- "/usr/bin/objdump", {"/usr/bin/objdump", "-d", *ObjectFilePath},
- std::nullopt, Redirects, 0, 0, &ErrMsg);
- auto StdOutBuf = MemoryBuffer::getFile(StdOutFile);
- if (StdOutBuf && !(*StdOutBuf)->getBuffer().empty())
- LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] Generated assembly:\n"
- << (*StdOutBuf)->getBuffer() << '\n');
- auto StdErrBuf = MemoryBuffer::getFile(StdErrFile);
- if (StdErrBuf && !(*StdErrBuf)->getBuffer().empty())
- LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] stderr:\n"
- << (*StdErrBuf)->getBuffer() << '\n');
- if (!ErrMsg.empty())
- LLVM_DEBUG(dbgs() << "[llvm-exegesis][objdump] process error: " << ErrMsg
- << '\n');
- sys::fs::remove(StdOutFile);
- sys::fs::remove(StdErrFile);
-#endif
}
if (BenchmarkPhaseSelector < BenchmarkPhaseSelectorE::Measure) {
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index babcffeb9666a..3ca0924cfbf2b 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -482,7 +482,8 @@ void benchmarkMain() {
InitializeAllExegesisTargets();
#define LLVM_EXEGESIS(TargetName) \
LLVMInitialize##TargetName##AsmPrinter(); \
- LLVMInitialize##TargetName##AsmParser();
+ LLVMInitialize##TargetName##AsmParser(); \
+ LLVMInitialize##TargetName##Disassembler();
#include "llvm/Config/TargetExegesis.def"
const LLVMState State = ExitOnErr(
@@ -635,6 +636,7 @@ static void analysisMain() {
InitializeAllExegesisTargets();
#define LLVM_EXEGESIS(TargetName) \
LLVMInitialize##TargetName##AsmPrinter(); \
+ LLVMInitialize##TargetName##AsmParser(); \
LLVMInitialize##TargetName##Disassembler();
#include "llvm/Config/TargetExegesis.def"
>From 8caf0413e0d665170f411b92189eb6e10b3eeb4e Mon Sep 17 00:00:00 2001
From: lakshayk-nv <lakshayk at nvidia.com>
Date: Mon, 30 Jun 2025 21:07:42 -0700
Subject: [PATCH 04/24] [llvm-exegesis] Clang format
---
llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 6e733f59a6b65..5acc3cbf480be 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -19,18 +19,18 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/MC/TargetRegistry.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
+#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/SystemZ/zOSSupport.h"
+#include "llvm/Support/TargetSelect.h"
#include <cmath>
#include <memory>
#include <string>
>From b57c3ab5cfca7058cb5a5bea8e1e5cfadcf7cc27 Mon Sep 17 00:00:00 2001
From: lakshayk-nv <lakshayk at nvidia.com>
Date: Mon, 30 Jun 2025 21:12:40 -0700
Subject: [PATCH 05/24] [llvm-exegesis] Cleanup changes
---
llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp | 2 +-
llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 5acc3cbf480be..857bc577767f4 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -649,7 +649,6 @@ BenchmarkRunner::getRunnableConfiguration(
BenchmarkResult.AssembledSnippet))
return std::move(Err);
}
-
// Assemble enough repetitions of the snippet so we have at least
// MinInstructions instructions.
if (BenchmarkPhaseSelector >
@@ -751,6 +750,7 @@ BenchmarkRunner::getRunnableConfiguration(
}
}
}
+
return std::move(RC);
}
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index 3ca0924cfbf2b..b5820f8669f1d 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -636,7 +636,6 @@ static void analysisMain() {
InitializeAllExegesisTargets();
#define LLVM_EXEGESIS(TargetName) \
LLVMInitialize##TargetName##AsmPrinter(); \
- LLVMInitialize##TargetName##AsmParser(); \
LLVMInitialize##TargetName##Disassembler();
#include "llvm/Config/TargetExegesis.def"
>From a56750fce1ff651f6f248573d77dfe86bd7b6223 Mon Sep 17 00:00:00 2001
From: abmajumder <abmajumder at nvidia.com>
Date: Tue, 6 May 2025 16:12:57 +0530
Subject: [PATCH 06/24] review comments
---
.../llvm-exegesis/lib/AArch64/Target.cpp | 42 +++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index d6f4c5220f71d..9063b7cbea12b 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -151,6 +151,48 @@ 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)) {
+#if defined(__aarch64__) && defined(__linux__)
+
+ // For some systems with existing PAC keys set, it is better to
+ // check the existing state of the key before setting it.
+ // For systems without PAC, this is a No-op but with PAC, it is
+ // safer to check the existing key state and then disable/enable them.
+ // Hence the guard placed for switching.
+ unsigned long pac_keys = 0;
+ if (prctl(PR_PAC_GET_ENABLED_KEYS, &pac_keys, 0, 0, 0) < 0) {
+ return "Failed to get PAC key status";
+ }
+
+ // 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 (pac_keys != 0) {
+ 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))
+ return "Unsupported opcode: load tag multiple";
+
+ return nullptr;
+ }
};
} // namespace
>From 7b3ead61e1020c428c68b437f38205cd2318e04a Mon Sep 17 00:00:00 2001
From: abmajumder <abmajumder at nvidia.com>
Date: Wed, 7 May 2025 17:12:59 +0530
Subject: [PATCH 07/24] review comments
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 9063b7cbea12b..40b39a2113334 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -166,7 +166,7 @@ class ExegesisAArch64Target : public ExegesisTarget {
// For systems without PAC, this is a No-op but with PAC, it is
// safer to check the existing key state and then disable/enable them.
// Hence the guard placed for switching.
- unsigned long pac_keys = 0;
+ unsigned long PacKeys = 0;
if (prctl(PR_PAC_GET_ENABLED_KEYS, &pac_keys, 0, 0, 0) < 0) {
return "Failed to get PAC key status";
}
@@ -174,7 +174,7 @@ class ExegesisAArch64Target : public ExegesisTarget {
// 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 (pac_keys != 0) {
+ if (PacKeys != 0) {
if (prctl(PR_PAC_SET_ENABLED_KEYS,
PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY |
PR_PAC_APDBKEY, // all keys
>From a45bd7a3d83cf0bdb8eaf95cb97bd51be935f3fc Mon Sep 17 00:00:00 2001
From: abmajumder <abmajumder at nvidia.com>
Date: Wed, 7 May 2025 20:25:25 +0530
Subject: [PATCH 08/24] typo build error
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 40b39a2113334..53f497e5da43e 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -165,9 +165,9 @@ class ExegesisAArch64Target : public ExegesisTarget {
// check the existing state of the key before setting it.
// For systems without PAC, this is a No-op but with PAC, it is
// safer to check the existing key state and then disable/enable them.
- // Hence the guard placed for switching.
+ // Hence the guard for switching.
unsigned long PacKeys = 0;
- if (prctl(PR_PAC_GET_ENABLED_KEYS, &pac_keys, 0, 0, 0) < 0) {
+ if (prctl(PR_PAC_GET_ENABLED_KEYS, &PacKeys, 0, 0, 0) < 0) {
return "Failed to get PAC key status";
}
>From b9d47e9b91f44a539aa4ff1f0d7527371a3e420d Mon Sep 17 00:00:00 2001
From: abmajumder <debabhi1396 at gmail.com>
Date: Fri, 9 May 2025 14:19:33 +0530
Subject: [PATCH 09/24] add einval condition and reviews
---
.../llvm-exegesis/lib/AArch64/Target.cpp | 32 ++++++++++++++-----
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 53f497e5da43e..6ee99d1aa8e02 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -10,6 +10,7 @@
#include "AArch64RegisterInfo.h"
#if defined(__aarch64__) && defined(__linux__)
+#include <errno.h>
#include <linux/prctl.h> // For PR_PAC_* constants
#include <sys/prctl.h>
#ifndef PR_PAC_APIAKEY
@@ -152,6 +153,11 @@ class ExegesisAArch64Target : public ExegesisTarget {
PM.add(createAArch64ExpandPseudoPass());
}
+ static long prctl_wrapper(int op, long arg2 = 0, long arg3 = 0, long arg4 = 0,
+ long arg5 = 0) {
+ return prctl(op, arg2, arg3, arg4, arg5);
+ }
+
const char *getIgnoredOpcodeReasonOrNull(const LLVMState &State,
unsigned Opcode) const override {
if (const char *Reason =
@@ -166,20 +172,30 @@ class ExegesisAArch64Target : public ExegesisTarget {
// For systems without PAC, this is a No-op but with PAC, it is
// safer to check the existing key state and then disable/enable them.
// Hence the guard for switching.
- unsigned long PacKeys = 0;
- if (prctl(PR_PAC_GET_ENABLED_KEYS, &PacKeys, 0, 0, 0) < 0) {
+ errno = 0;
+ unsigned long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS,
+ 0, // unused
+ 0, // unused
+ 0, // unused
+ 0); // unused
+ if ((long)PacKeys < 0) {
+ if (errno == EINVAL) {
+ return "PAuth not supported on this system";
+ }
return "Failed to get PAC key status";
}
// 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 (PacKeys != 0) {
- 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) {
+ if ((long)PacKeys != 0) {
+ if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS,
+ PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY |
+ PR_PAC_APDBKEY, // all keys
+ 0, // disable all
+ 0, // unused
+ 0) // unused
+ < 0) {
return "Failed to disable PAC keys";
}
}
>From 9680a821b6d8d1ec1b795061ab3bf745f845f081 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <30946547+abhilash1910 at users.noreply.github.com>
Date: Mon, 12 May 2025 18:15:47 +0530
Subject: [PATCH 10/24] Update llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
Co-authored-by: Anatoly Trosinenko <anatoly.trosinenko at gmail.com>
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 6ee99d1aa8e02..d0ae9b6a392a2 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -173,11 +173,7 @@ class ExegesisAArch64Target : public ExegesisTarget {
// safer to check the existing key state and then disable/enable them.
// Hence the guard for switching.
errno = 0;
- unsigned long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS,
- 0, // unused
- 0, // unused
- 0, // unused
- 0); // unused
+ unsigned long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS);
if ((long)PacKeys < 0) {
if (errno == EINVAL) {
return "PAuth not supported on this system";
>From 5f0876d25b0fe2c86ffce9747f35ea5b8b9b9c06 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <30946547+abhilash1910 at users.noreply.github.com>
Date: Mon, 12 May 2025 18:15:57 +0530
Subject: [PATCH 11/24] Update llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
Co-authored-by: Anatoly Trosinenko <anatoly.trosinenko at gmail.com>
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index d0ae9b6a392a2..b6544c17455a7 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -185,13 +185,13 @@ class ExegesisAArch64Target : public ExegesisTarget {
// be the same with PAC keys disabled, they could potentially be lower
// since authentication checks are bypassed.
if ((long)PacKeys != 0) {
- if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS,
- PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY |
- PR_PAC_APDBKEY, // all keys
- 0, // disable all
- 0, // unused
- 0) // unused
- < 0) {
+ // Operate on all keys.
+ const long KeysToControl =
+ PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY;
+ // Disable all.
+ const long EnabledBitMask = 0;
+ if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS, KeysToControl,
+ EnabledBitMask) < 0) {
return "Failed to disable PAC keys";
}
}
>From 54cac7a157d7ada6e2aff89ed2d57cff6fc3f5fe Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Mon, 12 May 2025 18:18:07 +0530
Subject: [PATCH 12/24] review updates
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index b6544c17455a7..46628575d0dc5 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -153,9 +153,10 @@ class ExegesisAArch64Target : public ExegesisTarget {
PM.add(createAArch64ExpandPseudoPass());
}
- static long prctl_wrapper(int op, long arg2 = 0, long arg3 = 0, long arg4 = 0,
- long arg5 = 0) {
- return prctl(op, arg2, arg3, arg4, arg5);
+ // Converts variadic arguments to `long` and passes zeros for the unused
+ // arg2-arg5, as tested by the Linux kernel.
+ static long prctl_wrapper(int op, long arg2 = 0, long arg3 = 0) {
+ return prctl(op, arg2, arg3, /*arg4=*/0L, /*arg5=*/0L);
}
const char *getIgnoredOpcodeReasonOrNull(const LLVMState &State,
>From 514c7f4547c1d94b77e6e208a3762b5792251387 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Mon, 12 May 2025 18:19:58 +0530
Subject: [PATCH 13/24] format fix
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 46628575d0dc5..c0bceba0be2c7 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -187,11 +187,11 @@ class ExegesisAArch64Target : public ExegesisTarget {
// since authentication checks are bypassed.
if ((long)PacKeys != 0) {
// Operate on all keys.
- const long KeysToControl =
+ const long KeysToControl =
PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY;
// Disable all.
const long EnabledBitMask = 0;
- if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS, KeysToControl,
+ if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS, KeysToControl,
EnabledBitMask) < 0) {
return "Failed to disable PAC keys";
}
>From 60a74917bc6bd34a2d91c3c6cee9bd9ea4b93e3e Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Mon, 12 May 2025 18:22:20 +0530
Subject: [PATCH 14/24] format fix
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index c0bceba0be2c7..fd19b37649fc2 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -167,7 +167,6 @@ class ExegesisAArch64Target : public ExegesisTarget {
if (isPointerAuth(Opcode)) {
#if defined(__aarch64__) && defined(__linux__)
-
// For some systems with existing PAC keys set, it is better to
// check the existing state of the key before setting it.
// For systems without PAC, this is a No-op but with PAC, it is
>From e958fa47c55bd0c5870af09540f30b3ea26d1517 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Tue, 13 May 2025 21:07:24 +0530
Subject: [PATCH 15/24] use nullptr as silentcondition
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index fd19b37649fc2..fceb232cf3976 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -153,11 +153,13 @@ class ExegesisAArch64Target : public ExegesisTarget {
PM.add(createAArch64ExpandPseudoPass());
}
+#if defined(__aarch64__) && defined(__linux__)
// Converts variadic arguments to `long` and passes zeros for the unused
// arg2-arg5, as tested by the Linux kernel.
static long prctl_wrapper(int op, long arg2 = 0, long arg3 = 0) {
return prctl(op, arg2, arg3, /*arg4=*/0L, /*arg5=*/0L);
}
+#endif
const char *getIgnoredOpcodeReasonOrNull(const LLVMState &State,
unsigned Opcode) const override {
@@ -175,9 +177,8 @@ class ExegesisAArch64Target : public ExegesisTarget {
errno = 0;
unsigned long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS);
if ((long)PacKeys < 0) {
- if (errno == EINVAL) {
- return "PAuth not supported on this system";
- }
+ if (errno == EINVAL)
+ return nullptr;
return "Failed to get PAC key status";
}
@@ -194,9 +195,12 @@ class ExegesisAArch64Target : public ExegesisTarget {
EnabledBitMask) < 0) {
return "Failed to disable PAC keys";
}
+ llvm::errs() << "llvm-exegesis: PAC keys were disabled at runtime for "
+ "benchmarking.\n";
}
#else
- return "Unsupported opcode: isPointerAuth";
+ // Silently return nullptr to ensure forward progress
+ return nullptr;
#endif
}
>From 9a8c19a26939855f24c63975bd205da0ed5da968 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Tue, 13 May 2025 21:40:41 +0530
Subject: [PATCH 16/24] use nullptr as silentcondition
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index fceb232cf3976..6beffa18aa299 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -176,11 +176,8 @@ class ExegesisAArch64Target : public ExegesisTarget {
// Hence the guard for switching.
errno = 0;
unsigned long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS);
- if ((long)PacKeys < 0) {
- if (errno == EINVAL)
- return nullptr;
- return "Failed to get PAC key status";
- }
+ if ((long)PacKeys < 0 || errno == EINVAL)
+ return nullptr;
// Disable all PAC keys. Note that while we expect the measurements to
// be the same with PAC keys disabled, they could potentially be lower
>From 73cab4c2cbfe5ff1dd9fa6462d4dd699767749d9 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Thu, 15 May 2025 23:16:02 +0530
Subject: [PATCH 17/24] update patch
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 6beffa18aa299..c995d46391d04 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -172,17 +172,20 @@ class ExegesisAArch64Target : public ExegesisTarget {
// For some systems with existing PAC keys set, it is better to
// check the existing state of the key before setting it.
// For systems without PAC, this is a No-op but with PAC, it is
- // safer to check the existing key state and then disable/enable them.
+ // better to check the existing key state and then disable/enable them
+ // to avoid runtime crashes owing to unsupported prctl opcodes or if the
+ // CPU implements FEAT_PAuth with FEAT_FPAC (in which case this method
+ // would silently return.).
// Hence the guard for switching.
errno = 0;
unsigned long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS);
- if ((long)PacKeys < 0 || errno == EINVAL)
+ if (static_cast<long> PacKeys < 0 || errno == EINVAL)
return nullptr;
// 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 ((long)PacKeys != 0) {
+ if (static_cast<long> PacKeys != 0) {
// Operate on all keys.
const long KeysToControl =
PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY;
>From ac6e98587d0af313d58838f218d831af863a6e62 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Fri, 23 May 2025 18:55:00 +0530
Subject: [PATCH 18/24] refine
---
.../llvm-exegesis/lib/AArch64/Target.cpp | 66 +++++++++++--------
llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 12 ++--
2 files changed, 47 insertions(+), 31 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index c995d46391d04..24439ced45490 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -169,34 +169,46 @@ class ExegesisAArch64Target : public ExegesisTarget {
if (isPointerAuth(Opcode)) {
#if defined(__aarch64__) && defined(__linux__)
- // For some systems with existing PAC keys set, it is better to
- // check the existing state of the key before setting it.
- // For systems without PAC, this is a No-op but with PAC, it is
- // better to check the existing key state and then disable/enable them
- // to avoid runtime crashes owing to unsupported prctl opcodes or if the
- // CPU implements FEAT_PAuth with FEAT_FPAC (in which case this method
- // would silently return.).
- // Hence the guard for switching.
- errno = 0;
- unsigned long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS);
- if (static_cast<long> PacKeys < 0 || errno == EINVAL)
- return nullptr;
-
- // 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 (static_cast<long> PacKeys != 0) {
- // Operate on all keys.
- const long KeysToControl =
- PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY;
- // Disable all.
- const long EnabledBitMask = 0;
- if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS, KeysToControl,
- EnabledBitMask) < 0) {
- return "Failed to disable PAC keys";
+ // Only proceed with PAC key control if explicitly requested
+ if (!AArch64DisablePacControl) {
+ // For some systems with existing PAC keys set, it is better to
+ // check the existing state of the key before setting it.
+ // For systems without PAC, this is a No-op but with PAC, it is
+ // better to check the existing key state and then disable/enable them
+ // to avoid runtime crashes owing to unsupported prctl opcodes or if the
+ // CPU implements FEAT_PAuth with FEAT_FPAC (in which case this method
+ // would silently return.). If the CPU implements FEAT_FPAC,
+ // authentication instructions almost certainly crash when being
+ // benchmarked, so disable all the keys by default. On the other hand,
+ // disabling the keys at run-time can probably crash llvm-exegesis at
+ // some later point, depending on how it was built. For that reason, the
+ // user may pass
+ // --COMMAND-LINE-OPTION-NAME in case llvm-exegesis crashes or
+ // instruction timings are affected. Hence the guard for switching.
+ errno = 0;
+ long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS);
+ if (PacKeys < 0 || errno == EINVAL)
+ return nullptr;
+
+ // 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.PR_PAC_* prctl operations
+ // return EINVAL when Pointer Authentication is not available, but no
+ // more errors are expected if we got here.
+ if (PacKeys != 0) {
+ // Operate on all keys.
+ const long KeysToControl =
+ PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY;
+ // Disable all.
+ const long EnabledBitMask = 0;
+ if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS, KeysToControl,
+ EnabledBitMask) < 0) {
+ return "Failed to disable PAC keys";
+ }
+ llvm::errs()
+ << "llvm-exegesis: PAC keys were disabled at runtime for "
+ "benchmarking.\n";
}
- llvm::errs() << "llvm-exegesis: PAC keys were disabled at runtime for "
- "benchmarking.\n";
}
#else
// Silently return nullptr to ensure forward progress
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index b5820f8669f1d..48285990f3b19 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -107,6 +107,12 @@ static cl::opt<Benchmark::RepetitionModeE> RepetitionMode(
"Middle half loop mode")),
cl::init(Benchmark::Duplicate));
+static cl::opt<bool> AArch64DisablePacControl(
+ "aarch64-disable-pac-control",
+ cl::desc("Disable PAC key control at runtime for benchmarking. Use this if "
+ "llvm-exegesis crashes or instruction timings are affected."),
+ cl::init(false));
+
static cl::opt<bool> BenchmarkMeasurementsPrintProgress(
"measurements-print-progress",
cl::desc("Produce progress indicator when performing measurements"),
@@ -444,8 +450,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();
@@ -644,8 +649,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 cad4ed0efc56c1d51eafc55c27fbe752d9fcb49d Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Tue, 27 May 2025 16:47:13 +0530
Subject: [PATCH 19/24] fix duplicate includes
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 24439ced45490..42c48a32cd698 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -11,8 +11,18 @@
#if defined(__aarch64__) && defined(__linux__)
#include <errno.h>
+<<<<<<< HEAD
#include <linux/prctl.h> // For PR_PAC_* constants
#include <sys/prctl.h>
+=======
+#include <sys/prctl.h> // For PR_PAC_* constants
+#ifndef PR_PAC_SET_ENABLED_KEYS
+#define PR_PAC_SET_ENABLED_KEYS 60
+#endif
+#ifndef PR_PAC_GET_ENABLED_KEYS
+#define PR_PAC_GET_ENABLED_KEYS 61
+#endif
+>>>>>>> 977612dd173f (fix duplicate includes)
#ifndef PR_PAC_APIAKEY
#define PR_PAC_APIAKEY (1UL << 0)
#endif
>From 90a50c8799f063475ef8f251e53b42c4deb40461 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Tue, 27 May 2025 16:51:15 +0530
Subject: [PATCH 20/24] clang-format
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 42c48a32cd698..c48eb82bd711d 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -11,11 +11,7 @@
#if defined(__aarch64__) && defined(__linux__)
#include <errno.h>
-<<<<<<< HEAD
-#include <linux/prctl.h> // For PR_PAC_* constants
-#include <sys/prctl.h>
-=======
-#include <sys/prctl.h> // For PR_PAC_* constants
+#include <sys/prctl.h> // For PR_PAC_* constants
#ifndef PR_PAC_SET_ENABLED_KEYS
#define PR_PAC_SET_ENABLED_KEYS 60
#endif
>From 1bb9f2f0545e66e80f43ec245ff95401766898b3 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Tue, 3 Jun 2025 11:39:41 +0530
Subject: [PATCH 21/24] refresh
---
.../llvm-exegesis/lib/AArch64/Target.cpp | 59 ++++++++++++++++---
1 file changed, 50 insertions(+), 9 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index c48eb82bd711d..ffe607af7cea1 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -8,6 +8,7 @@
#include "../Target.h"
#include "AArch64.h"
#include "AArch64RegisterInfo.h"
+#include "llvm/Support/CommandLine.h"
#if defined(__aarch64__) && defined(__linux__)
#include <errno.h>
@@ -39,6 +40,49 @@
namespace llvm {
namespace exegesis {
+extern llvm::cl::opt<bool> AArch64DisablePacControl;
+
+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,
+ // 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:
+ 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:
@@ -179,18 +223,14 @@ class ExegesisAArch64Target : public ExegesisTarget {
if (!AArch64DisablePacControl) {
// For some systems with existing PAC keys set, it is better to
// check the existing state of the key before setting it.
- // For systems without PAC, this is a No-op but with PAC, it is
- // better to check the existing key state and then disable/enable them
- // to avoid runtime crashes owing to unsupported prctl opcodes or if the
- // CPU implements FEAT_PAuth with FEAT_FPAC (in which case this method
- // would silently return.). If the CPU implements FEAT_FPAC,
+ // If the CPU implements FEAT_FPAC,
// authentication instructions almost certainly crash when being
// benchmarked, so disable all the keys by default. On the other hand,
// disabling the keys at run-time can probably crash llvm-exegesis at
// some later point, depending on how it was built. For that reason, the
- // user may pass
- // --COMMAND-LINE-OPTION-NAME in case llvm-exegesis crashes or
- // instruction timings are affected. Hence the guard for switching.
+ // user may pass --aarch64-disable-pac-control in case
+ // llvm-exegesis crashes or instruction timings are affected.
+ // Hence the guard for switching.
errno = 0;
long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS);
if (PacKeys < 0 || errno == EINVAL)
@@ -205,7 +245,8 @@ class ExegesisAArch64Target : public ExegesisTarget {
// Operate on all keys.
const long KeysToControl =
PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY;
- // Disable all.
+ // PR_PAC_* prctl operations return EINVAL when Pointer Authentication
+ // is not available but no more errors are expected if we got here.
const long EnabledBitMask = 0;
if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS, KeysToControl,
EnabledBitMask) < 0) {
>From 1e0e65c672bcdd7e47bd72f0fdf7a5083bdeb978 Mon Sep 17 00:00:00 2001
From: Abhilash Majumder <abmajumder at nvidia.com>
Date: Tue, 3 Jun 2025 22:35:04 +0530
Subject: [PATCH 22/24] refresh
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 6 +++++-
llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 14 +++++---------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index ffe607af7cea1..607196a0af67d 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -40,7 +40,11 @@
namespace llvm {
namespace exegesis {
-extern llvm::cl::opt<bool> AArch64DisablePacControl;
+static cl::opt<bool> AArch64DisablePacControl(
+ "aarch64-disable-pac-control",
+ cl::desc("Disable PAC key control at runtime for benchmarking. Use this if "
+ "llvm-exegesis crashes or instruction timings are affected."),
+ cl::init(false));
bool isPointerAuth(unsigned Opcode) {
switch (Opcode) {
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index 48285990f3b19..2114cabddcb42 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -107,12 +107,6 @@ static cl::opt<Benchmark::RepetitionModeE> RepetitionMode(
"Middle half loop mode")),
cl::init(Benchmark::Duplicate));
-static cl::opt<bool> AArch64DisablePacControl(
- "aarch64-disable-pac-control",
- cl::desc("Disable PAC key control at runtime for benchmarking. Use this if "
- "llvm-exegesis crashes or instruction timings are affected."),
- cl::init(false));
-
static cl::opt<bool> BenchmarkMeasurementsPrintProgress(
"measurements-print-progress",
cl::desc("Produce progress indicator when performing measurements"),
@@ -450,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();
@@ -649,7 +644,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;
@@ -739,4 +735,4 @@ int main(int Argc, char **Argv) {
exegesis::benchmarkMain();
}
return EXIT_SUCCESS;
-}
+}
\ No newline at end of file
>From 32c83865ed9cf6d38ddb65d572a9e5dc6a3229e7 Mon Sep 17 00:00:00 2001
From: lakshayk-nv <lakshayk at nvidia.com>
Date: Tue, 1 Jul 2025 01:40:50 -0700
Subject: [PATCH 23/24] newline
---
llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 1 -
llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 607196a0af67d..9297711d53612 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -19,7 +19,6 @@
#ifndef PR_PAC_GET_ENABLED_KEYS
#define PR_PAC_GET_ENABLED_KEYS 61
#endif
->>>>>>> 977612dd173f (fix duplicate includes)
#ifndef PR_PAC_APIAKEY
#define PR_PAC_APIAKEY (1UL << 0)
#endif
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index 2114cabddcb42..b5820f8669f1d 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -735,4 +735,4 @@ int main(int Argc, char **Argv) {
exegesis::benchmarkMain();
}
return EXIT_SUCCESS;
-}
\ No newline at end of file
+}
>From a8160ae429c3750938565a1063b208afa1dd698f Mon Sep 17 00:00:00 2001
From: lakshayk-nv <lakshayk at nvidia.com>
Date: Tue, 1 Jul 2025 01:43:55 -0700
Subject: [PATCH 24/24] [llvm-exegesis] [AArch64] Added testcase to check
assembly generation via debug-only
---
.../llvm-exegesis/AArch64/debug-gen-asm.s | 22 +++++++++++++++++++
.../llvm-exegesis/lib/BenchmarkRunner.cpp | 1 +
2 files changed, 23 insertions(+)
create mode 100644 llvm/test/tools/llvm-exegesis/AArch64/debug-gen-asm.s
diff --git a/llvm/test/tools/llvm-exegesis/AArch64/debug-gen-asm.s b/llvm/test/tools/llvm-exegesis/AArch64/debug-gen-asm.s
new file mode 100644
index 0000000000000..d1b96f02e3986
--- /dev/null
+++ b/llvm/test/tools/llvm-exegesis/AArch64/debug-gen-asm.s
@@ -0,0 +1,22 @@
+REQUIRES: aarch64-registered-target
+
+RUN: llvm-exegesis -mcpu=neoverse-v2 --benchmark-phase=measure --min-instructions=100 --mode=latency --debug-only="preview-gen-assembly" --opcode-name=ADDVv4i16v 2>&1 | FileCheck %s -check-prefix=PREVIEW
+
+PREVIEW: Generated assembly snippet:
+PREVIEW-NEXT: ```
+PREVIEW: {{.*}} movi d{{[0-9]+}}, #0000000000000000
+PREVIEW-NEXT: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
+PREVIEW: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
+PREVIEW: ... ({{[0-9]+}} more instructions)
+PREVIEW-NEXT: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
+PREVIEW: {{.*}} ret
+PREVIEW-NEXT:```
+
+RUN: llvm-exegesis -mcpu=neoverse-v2 --benchmark-phase=measure --min-instructions=100 --mode=latency --debug-only="print-gen-assembly" --opcode-name=ADDVv4i16v 2>&1 | FileCheck %s -check-prefix=PRINT
+
+PRINT: Generated assembly snippet:
+PRINT-NEXT: ```
+PRINT: {{.*}} movi d{{[0-9]+}}, #0000000000000000
+PRINT: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
+PRINT: {{.*}} ret
+PRINT-NEXT: ```
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 857bc577767f4..789326287f4e9 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -649,6 +649,7 @@ BenchmarkRunner::getRunnableConfiguration(
BenchmarkResult.AssembledSnippet))
return std::move(Err);
}
+
// Assemble enough repetitions of the snippet so we have at least
// MinInstructions instructions.
if (BenchmarkPhaseSelector >
More information about the llvm-commits
mailing list