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

-C llvm-args is parsed inconsistently within LLVM with the arguments llc accepts #26338

Closed
yongqli opened this issue Jun 16, 2015 · 12 comments · Fixed by #115638
Closed

-C llvm-args is parsed inconsistently within LLVM with the arguments llc accepts #26338

yongqli opened this issue Jun 16, 2015 · 12 comments · Fixed by #115638
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-bug Category: This is a bug. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-dev-tools Relevant to the dev-tools subteam, which will review and decide on the PR/issue.

Comments

@yongqli
Copy link

yongqli commented Jun 16, 2015

Please see this StackOverflow question.

@sanxiyn sanxiyn added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Jun 16, 2015
@nathanross
Copy link

Interesting:

rustc -C llvm-args='--list' gives the option list for LLC

you might expect llvm-args would be passed to clang (which has the options described in the stack overflow page), and indeed this seems to be the binary to which these arguments were formerly passed.

edit: but it also doesn't seem to be the case recently, as both stable and nightly seem to pass args to llc, not clang.

@Tyler-Hardin
Copy link

I think this may actually be a real thing.

See rust -C llvm-args='-soft-float'.

It throws the error:

rustc: Unknown command line argument '-soft-float'.  Try: 'rustc -help'
rustc: Did you mean '-asan-opt'?`

But llc definitely takes this argument. I've traced the argument parsing to llvm/lib/Support/CommandLine.cpp:CommandLineParser::ParseCommandLineOptions().

And now that I try it, --list doesn't seem to work for me either. I'm running 4c99649.

Btw, I ran into this trying to work around #26749.

@Tyler-Hardin
Copy link

Added code to print the argv passed to CommandLineParser::ParseCommandLineOptions(). It prints the args from llvm-args. So I guess the problem is that llc args != whatever arguments that function expects.

@JinShil
Copy link

JinShil commented Nov 4, 2016

So I guess the problem is that llc args != whatever arguments that function expects.

Yes, that appears to be the case.

The arguments recognized by llc and the arguments recognized by the llvm::cl::ParseCommandLineOptions() API are different. The Rust compiler uses the LLVM API, so it doesn't recognize certain LLVM options even though they may be valid for llc.

Consider the following:

#include "llvm/Support/CommandLine.h"

using namespace llvm;

int main(int argc, char** argv) {
    cl::ParseCommandLineOptions(argc, argv, "");

    return 0;
}

Compile with g++ hello.cc -lLLVM-3.8.1 and execute with a.out -help. It will print the following:

OVERVIEW: 
USAGE: a.out [options]

OPTIONS:

General options:

  -aarch64-neon-syntax                            - Choose style of NEON code to emit from AArch64 backend:
    =generic                                      -   Emit generic NEON assembly
    =apple                                        -   Emit Apple-style NEON assembly
  -bounds-checking-single-trap                    - Use one trap block per function
  -color                                          - use colored syntax highlighting (default=autodetect)
  -cppfname=<function name>                       - Specify the name of the generated function
  -cppfor=<string>                                - Specify the name of the thing to generate
  -cppgen                                         - Choose what kind of output to generate
    =program                                      -   Generate a complete program
    =module                                       -   Generate a module definition
    =contents                                     -   Generate contents of a module
    =function                                     -   Generate a function definition
    =functions                                    -   Generate all function definitions
    =inline                                       -   Generate an inline function
    =variable                                     -   Generate a variable definition
    =type                                         -   Generate a type definition
  -disable-spill-fusing                           - Disable fusing of spill code into instructions
  -enable-implicit-null-checks                    - Fold null checks into faulting memory operations
  -enable-load-pre                                - 
  -enable-objc-arc-opts                           - enable/disable all ARC Optimizations
  -enable-scoped-noalias                          - 
  -enable-tbaa                                    - 
  -exhaustive-register-search                     - Exhaustive Search for registers bypassing the depth and interference cutoffs of last chance recoloring
  -filter-print-funcs=<function names>            - Only print IR for functions whose name match this for all print-[before|after][-all] options
  -gpsize=<uint>                                  - Global Pointer Addressing Size.  The default size is 8.
  -imp-null-check-page-size=<uint>                - The page size of the target in bytes
  -internalize-public-api-file=<filename>         - A file containing list of symbol names to preserve
  -internalize-public-api-list=<list>             - A list of symbol names to preserve
  -join-liveintervals                             - Coalesce copies (default=true)
  -limit-float-precision=<uint>                   - Generate low-precision inline sequences for some float libcalls
  -merror-missing-parenthesis                     - Error for missing parenthesis around predicate registers
  -merror-noncontigious-register                  - Error for register names that aren't contigious
  -mfuture-regs                                   - Enable future registers
  -mips16-constant-islands                        - Enable mips16 constant islands.
  -mips16-hard-float                              - Enable mips16 hard float.
  -mno-compound                                   - Disable looking for compound instructions for Hexagon
  -mno-ldc1-sdc1                                  - Expand double precision loads and stores to their single precision counterparts
  -mno-pairing                                    - Disable looking for duplex instructions for Hexagon
  -mwarn-missing-parenthesis                      - Warn for missing parenthesis around predicate registers
  -mwarn-noncontigious-register                   - Warn for register names that arent contigious
  -mwarn-sign-mismatch                            - Warn for mismatching a signed and unsigned value
  -no-discriminators                              - Disable generation of discriminator information.
  -nvptx-sched4reg                                - NVPTX Specific: schedule for register pressue
  -print-after-all                                - Print IR after each pass
  -print-before-all                               - Print IR before each pass
  -print-machineinstrs=<pass-name>                - Print machine instrs
  -rdf-dump                                       - 
  -rdf-limit=<uint>                               - 
  -regalloc                                       - Register allocator to use
    =default                                      -   pick register allocator based on -O option
    =basic                                        -   basic register allocator
    =fast                                         -   fast register allocator
    =greedy                                       -   greedy register allocator
    =pbqp                                         -   PBQP register allocator
  -rewrite-map-file=<filename>                    - Symbol Rewrite Map
  -rng-seed=<seed>                                - Seed for the random number generator
  -sample-profile-check-record-coverage=<N>       - Emit a warning if less than N% of records in the input profile are matched to the IR.
  -sample-profile-check-sample-coverage=<N>       - Emit a warning if less than N% of samples in the input profile are matched to the IR.
  -sample-profile-global-cold-threshold=<N>       - Top-level functions that account for less than N% of all samples collected in the profile, will be marked as cold for the inliner to consider.
  -sample-profile-global-hot-threshold=<N>        - Top-level functions that account for more than N% of all samples collected in the profile, will be marked as hot for the inliner to consider.
  -sample-profile-inline-hot-threshold=<N>        - Inlined functions that account for more than N% of all samples collected in the parent function, will be inlined again.
  -sample-profile-max-propagate-iterations=<uint> - Maximum number of iterations to go through when propagating sample block/edge weights through the CFG.
  -stackmap-version=<int>                         - Specify the stackmap encoding version (default = 1)
  -stats                                          - Enable statistics output from program (available with Asserts)
  -summary-file=<string>                          - The summary file to use for function importing.
  -time-passes                                    - Time each pass, printing elapsed time for each on exit
  -verify-debug-info                              - 
  -verify-dom-info                                - Verify dominator info (time consuming)
  -verify-loop-info                               - Verify loop info (time consuming)
  -verify-regalloc                                - Verify during register allocation
  -verify-region-info                             - Verify region info (time consuming)
  -verify-scev                                    - Verify ScalarEvolution's backedge taken counts (slow)
  -x86-asm-syntax                                 - Choose style of code to emit from X86 backend:
    =att                                          -   Emit AT&T-style assembly
    =intel                                        -   Emit Intel-style assembly

Generic Options:

  -help                                           - Display available options (-help-hidden for more)
  -help-list                                      - Display list of available options (-help-list-hidden for more)
  -version                                        - Display the version of this program

Compare that with the output for llc -help (an exercise left to the reader). I need the -function-sections and -data-sections for my target, as they don't appear to be enabled by default.

I don't know what the solution is here. Is it something for LLVM to solve, or something for rustc to solve?

@Mark-Simulacrum Mark-Simulacrum changed the title llvm-args don't work -C llvm-args is parsed inconsistently within LLVM with the arguments llc accepts May 15, 2017
@Mark-Simulacrum
Copy link
Member

I'm leaving this open because it's not clear to me how a user should pass arguments directly to llc if they want to; perhaps that's not possible or even something we want. @rust-lang/compiler: Could you comment on whether we think it's a good idea to allow passing arguments into llc directly? Do we run llc at all? If we don't then it seems that this is not a bug.

@Mark-Simulacrum Mark-Simulacrum added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 22, 2017
@Mark-Simulacrum
Copy link
Member

Nominating to decide whether we want to expose llc or not (and if we can -- I don't know that we run it directly today). If not, we should close.

@nikomatsakis nikomatsakis added T-dev-tools Relevant to the dev-tools subteam, which will review and decide on the PR/issue. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 6, 2017
@nikomatsakis
Copy link
Contributor

I'm moving this to T-dev-tools; it seems like they've put some energy into how to think about the stability of llvm-args #40063 as well.

@nrc
Copy link
Member

nrc commented Jul 10, 2017

cc @alexcrichton @vadimcn this seems like something that would be a tooling/platform team issue if that team existed.

@nrc nrc added P-low Low priority and removed I-nominated labels Jul 10, 2017
@nrc
Copy link
Member

nrc commented Jul 10, 2017

Briefly discussed at the dev-tools meeting: verdict was that this did not seem urgent to address.

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@jethrogb
Copy link
Contributor

jethrogb commented Jan 9, 2020

Related #68059

@workingjubilee workingjubilee added the A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. label Mar 3, 2023
@Noratrieb Noratrieb added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Apr 5, 2023
@sethp
Copy link
Contributor

sethp commented Apr 26, 2023

Leaving this here in case it's helpful to anyone who comes across this issue: I was able to get what appears to be the full list of the arguments LLVM will accept by way of -C llvm-args with:

rustc -C llvm-args='--help-list-hidden'

Caution: sharp edges abound.

@nikic
Copy link
Contributor

nikic commented Apr 26, 2023

Exposing these flags would be a matter of using RegisterCodeGenFlags, if we really want to.

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Sep 7, 2023
`-Cllvm-args` usability improvement

fixes: rust-lang#26338
fixes: rust-lang#115564

Two problems were found during playing with `-Cllvm-args`

1. When `llvm.link-shared` is set to `false` in `config.toml`, output of `rustc -C llvm-args='--help-list-hidden'` doesn't contain `--emit-dwarf-unwind` and `--emulated-tls`. When it is set to `true`, `rustc -C llvm-args='--help-list-hidden'` emits `--emit-dwarf-unwind`, but `--emulated-tls` is still missing.
2. Setting `-Cllvm-args=--emit-dwarf-unwind=always` doesn't take any effect, but `-Cllvm-args=-machine-outliner-reruns=3` does work.

### 1

Adding `RegisterCodeGenFlags` to register codegen flags fixed the first problem. `rustc -C llvm-args='--help-list-hidden'` emits full codegen flags including `--emit-dwarf-unwind` and `--emulated-tls`.

### 2

Constructing `TargetOptions` from `InitTargetOptionsFromCodeGenFlags` in `LLVMRustCreateTargetMachine` fixed the second problem. The `LLVMRustSetLLVMOptions` calls `ParseCommandLineOptions` which parses given `llvm-args`. For options like `machine-outliner-reruns`, it just works, since the codegen logic directly consumes the parsing result:

[machine-outliner-reruns register](https://github.com/rust-lang/llvm-project/blob/0537f6354cffe546cbf47f6dc9c7f82e49e86cfb/llvm/lib/CodeGen/MachineOutliner.cpp#L114)
[machine-outliner-reruns consumption](https://github.com/rust-lang/llvm-project/blob/0537f6354cffe546cbf47f6dc9c7f82e49e86cfb/llvm/lib/CodeGen/MachineOutliner.cpp#L1138)

But for flags defined in `TargetOptions` and `MCTargetOptions` to take effect, constructing them with `InitTargetOptionsFromCodeGenFlags` is essential, or the parsing result is just not consumed. Similar patterns can be observed in [lli](https://github.com/rust-lang/llvm-project/blob/0537f6354cffe546cbf47f6dc9c7f82e49e86cfb/llvm/tools/llc/llc.cpp#L494), [llc](https://github.com/rust-lang/llvm-project/blob/0537f6354cffe546cbf47f6dc9c7f82e49e86cfb/llvm/tools/lli/lli.cpp#L517), etc.
@bors bors closed this as completed in 575c363 Sep 8, 2023
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Sep 8, 2023
Rollup merge of rust-lang#115638 - ldm0:ldm/llvm-args-fix, r=nikic

`-Cllvm-args` usability improvement

fixes: rust-lang#26338
fixes: rust-lang#115564

Two problems were found during playing with `-Cllvm-args`

1. When `llvm.link-shared` is set to `false` in `config.toml`, output of `rustc -C llvm-args='--help-list-hidden'` doesn't contain `--emit-dwarf-unwind` and `--emulated-tls`. When it is set to `true`, `rustc -C llvm-args='--help-list-hidden'` emits `--emit-dwarf-unwind`, but `--emulated-tls` is still missing.
2. Setting `-Cllvm-args=--emit-dwarf-unwind=always` doesn't take any effect, but `-Cllvm-args=-machine-outliner-reruns=3` does work.

### 1

Adding `RegisterCodeGenFlags` to register codegen flags fixed the first problem. `rustc -C llvm-args='--help-list-hidden'` emits full codegen flags including `--emit-dwarf-unwind` and `--emulated-tls`.

### 2

Constructing `TargetOptions` from `InitTargetOptionsFromCodeGenFlags` in `LLVMRustCreateTargetMachine` fixed the second problem. The `LLVMRustSetLLVMOptions` calls `ParseCommandLineOptions` which parses given `llvm-args`. For options like `machine-outliner-reruns`, it just works, since the codegen logic directly consumes the parsing result:

[machine-outliner-reruns register](https://github.com/rust-lang/llvm-project/blob/0537f6354cffe546cbf47f6dc9c7f82e49e86cfb/llvm/lib/CodeGen/MachineOutliner.cpp#L114)
[machine-outliner-reruns consumption](https://github.com/rust-lang/llvm-project/blob/0537f6354cffe546cbf47f6dc9c7f82e49e86cfb/llvm/lib/CodeGen/MachineOutliner.cpp#L1138)

But for flags defined in `TargetOptions` and `MCTargetOptions` to take effect, constructing them with `InitTargetOptionsFromCodeGenFlags` is essential, or the parsing result is just not consumed. Similar patterns can be observed in [lli](https://github.com/rust-lang/llvm-project/blob/0537f6354cffe546cbf47f6dc9c7f82e49e86cfb/llvm/tools/llc/llc.cpp#L494), [llc](https://github.com/rust-lang/llvm-project/blob/0537f6354cffe546cbf47f6dc9c7f82e49e86cfb/llvm/tools/lli/lli.cpp#L517), etc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-bug Category: This is a bug. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-dev-tools Relevant to the dev-tools subteam, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.