[llvm] 7617797 - [opt] Enable -mcpu=help without an input file (#187876)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 24 01:30:37 PDT 2026


Author: Tomer Shafir
Date: 2026-03-24T10:30:32+02:00
New Revision: 76177971a8f74f533a136577b8f709df96cd6b37

URL: https://github.com/llvm/llvm-project/commit/76177971a8f74f533a136577b8f709df96cd6b37
DIFF: https://github.com/llvm/llvm-project/commit/76177971a8f74f533a136577b8f709df96cd6b37.diff

LOG: [opt] Enable -mcpu=help without an input file (#187876)

This patch enables `-mcpu=help` or `-mattr=help` invocation without an
input file, like `llc`. For example, the following command `opt
-mtriple=aarch64 -mattr=help` would previously hang but now it succeeds.

The implementation is similar to llc, creating a target machine for help
printing side effects and existing early. Note: llc has a bug in the
default triple handling that we already fix here upfront. Ill submit a
separate fix for llc.

Added: 
    llvm/test/tools/opt/mattr-mcpu-help.ll

Modified: 
    llvm/tools/opt/optdriver.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/opt/mattr-mcpu-help.ll b/llvm/test/tools/opt/mattr-mcpu-help.ll
new file mode 100644
index 0000000000000..c4de602d00540
--- /dev/null
+++ b/llvm/test/tools/opt/mattr-mcpu-help.ll
@@ -0,0 +1,34 @@
+; REQUIRES: aarch64-registered-target
+; REQUIRES: default_triple
+
+;; Test -mattr=help
+; RUN: opt -mtriple=aarch64 -mattr=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+; RUN: opt -mtriple=aarch64 -mattr=help -o %t.s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+; RUN: opt < %s -mtriple=aarch64 -mattr=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+; RUN: opt < %s -mtriple=aarch64 -mattr=help -o %t.s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+
+;; -mattr=help doesn't have to be first
+; RUN: opt -mtriple=aarch64 -mattr=+zcm-fpr64 -mattr=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+
+;; Using default target triple for -mattr=help
+; RUN: opt -mattr=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+; RUN: opt < %s -mattr=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+
+;; Test -mcpu=help
+; RUN: opt -mtriple=aarch64 -mcpu=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+; RUN: opt -mtriple=aarch64 -mcpu=help -o %t.s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+; RUN: opt < %s -mtriple=aarch64 -mcpu=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+; RUN: opt < %s -mtriple=aarch64 -mcpu=help -o %t.s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+
+;; Using default target triple for -mcpu=help
+; RUN: opt -mcpu=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+; RUN: opt < %s -mcpu=help 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-OPTIMIZE
+
+; CHECK: Available CPUs for this target:
+; CHECK: Available features for this target:
+
+;; To check we dont compile the file
+; CHECK-NO-OPTIMIZE-NOT: foo
+define i32 @foo() {
+  ret i32 0
+}

diff  --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index 2d1613edc2c83..2a6f0d4cb238a 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -488,6 +488,33 @@ optMain(int argc, char **argv,
     return 0;
   }
 
+  // If user just wants to list available options, skip module loading.
+  auto MAttrs = codegen::getMAttrs();
+  bool SkipModule =
+      codegen::getCPUStr() == "help" || is_contained(MAttrs, "help");
+  if (SkipModule) {
+    Triple TheTriple;
+    if (!TargetTriple.empty())
+      TheTriple = Triple(Triple::normalize(TargetTriple));
+    else
+      TheTriple = Triple(sys::getDefaultTargetTriple());
+
+    // Create the target machine just to print the help info. Use unique_ptr
+    // to avoid a memory leak.
+    Expected<std::unique_ptr<TargetMachine>> ExpectedTM =
+        codegen::createTargetMachineForTriple(TheTriple.str(),
+                                              GetCodeGenOptLevel());
+    if (Error E = ExpectedTM.takeError()) {
+      errs() << argv[0] << ": " << toString(std::move(E)) << "\n";
+      return 1;
+    }
+
+    // If we don't have a module then just exit now. We do this down
+    // here since the CPU/Feature help is underneath the target machine
+    // creation.
+    return 0;
+  }
+
   TimeTracerRAII TimeTracer(argv[0]);
 
   SMDiagnostic Err;


        


More information about the llvm-commits mailing list