Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Exegesis] CPU selection, when native arch and target mismatch #131014

Merged
merged 1 commit into from
Mar 26, 2025

Conversation

AnastasiyaChernikova
Copy link
Contributor

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Mar 12, 2025

@llvm/pr-subscribers-tools-llvm-exegesis

Author: None (AnastasiyaChernikova)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/131014.diff

2 Files Affected:

  • (modified) llvm/tools/llvm-exegesis/lib/LlvmState.cpp (+6)
  • (modified) llvm/tools/llvm-exegesis/llvm-exegesis.cpp (+5)
diff --git a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
index 9502cae993f67..af885a764124b 100644
--- a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
+++ b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
@@ -45,6 +45,12 @@ Expected<LLVMState> LLVMState::Create(std::string TripleName,
   if (CpuName == "native")
     CpuName = std::string(sys::getHostCPUName());
 
+  if (CpuName.empty()) {
+    std::unique_ptr<MCSubtargetInfo> Empty_STI(
+        TheTarget->createMCSubtargetInfo(TripleName, "", ""));
+    CpuName = Empty_STI->getAllProcessorDescriptions().begin()->Key;
+  }
+
   std::unique_ptr<MCSubtargetInfo> STI(
       TheTarget->createMCSubtargetInfo(TripleName, CpuName, ""));
   assert(STI && "Unable to create subtarget info!");
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index babcffeb9666a..6a37637dcebee 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -44,6 +44,7 @@
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/TargetParser/Host.h"
+#include "llvm/TargetParser/Triple.h"
 #include <algorithm>
 #include <string>
 
@@ -479,6 +480,10 @@ void benchmarkMain() {
 #endif
   }
 
+  // case for cross generating, when native arch and target mismatch
+  if (Triple(sys::getProcessTriple()).getArch() != Triple(TripleName).getArch())
+    MCPU = "";
+
   InitializeAllExegesisTargets();
 #define LLVM_EXEGESIS(TargetName)                                              \
   LLVMInitialize##TargetName##AsmPrinter();                                    \

Copy link

github-actions bot commented Mar 13, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@boomanaiden154 boomanaiden154 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have more information on the intended use case for this? I'm struggling to contextualize it.

@AnastasiyaChernikova
Copy link
Contributor Author

At the moment, when building llvm-exegesis for RISC-V, the --mcpu flag must be specified. If this flag is omitted, the mcpu of the architecture of the device on which the assembly takes place (often ARM or x86) will be automatically set. To address this issue, I suggest making the following changes: if the launch line does not contain the mcpu when building for a different architecture, the first one from the list of mcpu for the target architecture will be automatically selected.

Copy link
Contributor

@boomanaiden154 boomanaiden154 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment, when building llvm-exegesis for RISC-V, the --mcpu flag must be specified. If this flag is omitted, the mcpu of the architecture of the device on which the assembly takes place (often ARM or x86) will be automatically set. To address this issue, I suggest making the following changes: if the launch line does not contain the mcpu when building for a different architecture, the first one from the list of mcpu for the target architecture will be automatically selected.

Is the first CPU in the list always a sensible choice? I think it would make more sense to just error out if the user species -mcpu=native when the target arch is set to something different than the host.

@AnastasiyaChernikova
Copy link
Contributor Author

At the moment, when building llvm-exegesis for RISC-V, the --mcpu flag must be specified. If this flag is omitted, the mcpu of the architecture of the device on which the assembly takes place (often ARM or x86) will be automatically set. To address this issue, I suggest making the following changes: if the launch line does not contain the mcpu when building for a different architecture, the first one from the list of mcpu for the target architecture will be automatically selected.

Is the first CPU in the list always a sensible choice? I think it would make more sense to just error out if the user species -mcpu=native when the target arch is set to something different than the host.

In this case, we are talking about a situation where the user does not set any mcpu. In this scenario, exegesis itself puts the mcpu in native. And already during the processing process, the basic mcpu of the architecture on which the assembly is taking place is substituted. I believe that when the mcpu is not set by the user, it is assumed that just the basic one will be used, as it is done in the case of non-cross compilation. That's the functionality I'm offering here.
Regarding the first item from the list - I agree. Replaced with the choice of generic.

@boomanaiden154
Copy link
Contributor

In this case, we are talking about a situation where the user does not set any mcpu. In this scenario, exegesis itself puts the mcpu in native.

Right. I understand that part.

And already during the processing process, the basic mcpu of the architecture on which the assembly is taking place is substituted. I believe that when the mcpu is not set by the user, it is assumed that just the basic one will be used, as it is done in the case of non-cross compilation. That's the functionality I'm offering here.
Regarding the first item from the list - I agree. Replaced with the choice of generic.

I'm not sure basing how llvm-exegesis should behave on how the -mcpu flag is treated in clang is a good idea. Building a scheduling model requires pretty exact knowledge of the CPU it is being run on, which is why I presume the default was -mcpu=native rather than -mcpu=generic or something else.

What would be the drawback of simply erroring out if we detect cross compilation with -mcpu=native and error out, telling the user to specify a specific CPU?

@AnastasiyaChernikova
Copy link
Contributor Author

AnastasiyaChernikova commented Mar 17, 2025

In this case, we are talking about a situation where the user does not set any mcpu. In this scenario, exegesis itself puts the mcpu in native.

Right. I understand that part.

And already during the processing process, the basic mcpu of the architecture on which the assembly is taking place is substituted. I believe that when the mcpu is not set by the user, it is assumed that just the basic one will be used, as it is done in the case of non-cross compilation. That's the functionality I'm offering here.
Regarding the first item from the list - I agree. Replaced with the choice of generic.

I'm not sure basing how llvm-exegesis should behave on how the -mcpu flag is treated in clang is a good idea. Building a scheduling model requires pretty exact knowledge of the CPU it is being run on, which is why I presume the default was -mcpu=native rather than -mcpu=generic or something else.

What would be the drawback of simply erroring out if we detect cross compilation with -mcpu=native and error out, telling the user to specify a specific CPU?

It seems to me that the logic would be incorrect. In general, the mcpu flag is not required for exegesis assembly in the general case. Making this mandatory for cross-compilation seems strange to me. After all, the main idea of setting this flag is to choose a specific feature. And if mcpu is not specified, it means the user doesn't care about the implementation nuances

@AnastasiyaChernikova
Copy link
Contributor Author

AnastasiyaChernikova commented Mar 17, 2025

I suggest to set default value for mcpu to be an empty string and move the logic of selecting default cpu to LlvmState.cpp:

In case of cross-compilation select 'generic' by default and raise an error if user manually specified 'native'. Otherwise - in case of host compilation, set cpu to 'native' by default.

@boomanaiden154 Would that be better?

@boomanaiden154
Copy link
Contributor

In case of cross-compilation select 'generic' by default and raise an error if user manually specified 'native'. Otherwise - in case of host compilation, set cpu to 'native' by default.

This still doesn't address the problem that I have with the current approach. If we are not cross compiling, we know the target CPU uarch because we can just query it. If we are cross compiling, then we do not know the target CPU. Maybe things outside of analysis mode will mostly work fine with a generic CPU, but I see no reason why we shouldn't require the user to specify an exact CPU (ie error out if -mcpu is not specified when cross compiling). This probably improves the exegesis user experience. The user is required to specify a CPU which takes a little bit of extra effort, but won't be wondering about issues like why certain ISA extensions are suspiciously not getting any coverage.

@AnastasiyaChernikova
Copy link
Contributor Author

In case of cross-compilation select 'generic' by default and raise an error if user manually specified 'native'. Otherwise - in case of host compilation, set cpu to 'native' by default.

This still doesn't address the problem that I have with the current approach. If we are not cross compiling, we know the target CPU uarch because we can just query it. If we are cross compiling, then we do not know the target CPU. Maybe things outside of analysis mode will mostly work fine with a generic CPU, but I see no reason why we shouldn't require the user to specify an exact CPU (ie error out if -mcpu is not specified when cross compiling). This probably improves the exegesis user experience. The user is required to specify a CPU which takes a little bit of extra effort, but won't be wondering about issues like why certain ISA extensions are suspiciously not getting any coverage.

Okay, I agree. Replaced with error output.

if ((Triple(sys::getProcessTriple()).getArch() !=
Triple(TripleName).getArch()) &&
(MCPU == "native"))
ExitWithError("Incorrect cpu. To see all possible options use -mcpu=help");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be a bit more descriptive here? Maybe something like A CPU must be explicitly specified when cross compiling. To see all possible options use -mcpu=help?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

Copy link
Contributor

@boomanaiden154 boomanaiden154 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but please wait for approval from Min as well before merging.

Copy link
Member

@mshockwave mshockwave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@AnastasiyaChernikova AnastasiyaChernikova merged commit 6ecc67f into llvm:main Mar 26, 2025
11 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 26, 2025

LLVM Buildbot has detected a new failure on builder llvm-nvptx-nvidia-ubuntu running on as-builder-7 while building llvm at step 6 "test-build-unified-tree-check-llvm".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/180/builds/15396

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-llvm) failure: test (failure)
******************** TEST 'LLVM :: tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
not /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llvm-exegesis -mtriple=riscv64-unknown-linux-gnu -mode=latency --benchmark-phase=assemble-measured-code -opcode-name=ADD 2>&1 | /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s # RUN: at line 1
+ not /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llvm-exegesis -mtriple=riscv64-unknown-linux-gnu -mode=latency --benchmark-phase=assemble-measured-code -opcode-name=ADD
+ /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s
/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s:3:10: error: CHECK: expected string not found in input
# CHECK: llvm-exegesis error: A CPU must be explicitly specified when cross compiling. To see all possible options for riscv64-unknown-linux-gnu triple use -mcpu=help
         ^
<stdin>:1:1: note: scanning from here
llvm-exegesis error: no LLVM target for triple riscv64-unknown-linux-gnu
^

Input file: <stdin>
Check file: /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s

-dump-input=help explains the following input dump.

Input was:
<<<<<<
         1: llvm-exegesis error: no LLVM target for triple riscv64-unknown-linux-gnu 
check:3     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
>>>>>>

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 26, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-sie-ubuntu-fast running on sie-linux-worker while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/21316

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
not /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/llvm-exegesis -mtriple=riscv64-unknown-linux-gnu -mode=latency --benchmark-phase=assemble-measured-code -opcode-name=ADD 2>&1 | /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s # RUN: at line 1
+ not /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/llvm-exegesis -mtriple=riscv64-unknown-linux-gnu -mode=latency --benchmark-phase=assemble-measured-code -opcode-name=ADD
+ /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s
�[1m/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s:3:10: �[0m�[0;1;31merror: �[0m�[1mCHECK: expected string not found in input
�[0m# CHECK: llvm-exegesis error: A CPU must be explicitly specified when cross compiling. To see all possible options for riscv64-unknown-linux-gnu triple use -mcpu=help
�[0;1;32m         ^
�[0m�[1m<stdin>:1:1: �[0m�[0;1;30mnote: �[0m�[1mscanning from here
�[0mllvm-exegesis error: no LLVM target for triple riscv64-unknown-linux-gnu
�[0;1;32m^
�[0m
Input file: <stdin>
Check file: /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s

-dump-input=help explains the following input dump.

Input was:
<<<<<<
�[1m�[0m�[0;1;30m         1: �[0m�[1m�[0;1;46mllvm-exegesis error: no LLVM target for triple riscv64-unknown-linux-gnu �[0m
�[0;1;31mcheck:3     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
�[0m>>>>>>

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 26, 2025

LLVM Buildbot has detected a new failure on builder llvm-nvptx64-nvidia-ubuntu running on as-builder-7 while building llvm at step 6 "test-build-unified-tree-check-llvm".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/160/builds/15399

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-llvm) failure: test (failure)
******************** TEST 'LLVM :: tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
not /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llvm-exegesis -mtriple=riscv64-unknown-linux-gnu -mode=latency --benchmark-phase=assemble-measured-code -opcode-name=ADD 2>&1 | /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s # RUN: at line 1
+ not /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llvm-exegesis -mtriple=riscv64-unknown-linux-gnu -mode=latency --benchmark-phase=assemble-measured-code -opcode-name=ADD
+ /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s
/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s:3:10: error: CHECK: expected string not found in input
# CHECK: llvm-exegesis error: A CPU must be explicitly specified when cross compiling. To see all possible options for riscv64-unknown-linux-gnu triple use -mcpu=help
         ^
<stdin>:1:1: note: scanning from here
llvm-exegesis error: no LLVM target for triple riscv64-unknown-linux-gnu
^

Input file: <stdin>
Check file: /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/tools/llvm-exegesis/X86/mcpu_not_set_during_cross_compilation.s

-dump-input=help explains the following input dump.

Input was:
<<<<<<
         1: llvm-exegesis error: no LLVM target for triple riscv64-unknown-linux-gnu 
check:3     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
>>>>>>

--

********************


@dyung
Copy link
Collaborator

dyung commented Mar 26, 2025

@AnastasiyaChernikova the test you added is failing on several bots. I believe the problem is you are assuming the riscv target is being built, and the test fails on bots where it is not being built (at least for my bots). Can you take a look and fix or revert if you need time to investigate?

@boomanaiden154
Copy link
Contributor

1876a89 should fix that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants