Questions tagged [llvm-codegen]

Questions about how LLVM generates machine code from LLVM-IR or high-level languages. If you are asking about a specific CPU architecture, please also add that corresponding tag (e.g. `x86`).

LLVM's main use is to generate (CPU dependent) machine code from LLVM-IR. This LLVM-IR is often generated by a compiler of a high-level language (e.g. clang++ for C++ code or rustc for Rust code). This tag hosts all questions about the translation of LLVM-IR or high-level languages to machine code. Example: "How is a 128-bit LLVM integer implemented on 64-bit hardware?"

45 questions
567
votes
6 answers

Does the C++ standard allow for an uninitialized bool to crash a program?

I know that an "undefined behaviour" in C++ can pretty much allow the compiler to do anything it wants. However, I had a crash that surprised me, as I assumed that the code was safe enough. In this case, the real problem happened only on a specific…
Remz
  • 3,338
  • 3
  • 7
  • 11
403
votes
1 answer

Why does the Rust compiler not optimize code assuming that two mutable references cannot alias?

As far as I know, reference/pointer aliasing can hinder the compiler's ability to generate optimized code, since they must ensure the generated binary behaves correctly in the case where the two references/pointers indeed alias. For instance, in the…
Zhiyao
  • 4,152
  • 2
  • 12
  • 21
259
votes
2 answers

Why is there a large performance impact when looping over an array with 240 or more elements?

When running a sum loop over an array in Rust, I noticed a huge performance drop when CAPACITY >= 240. CAPACITY = 239 is about 80 times faster. Is there special compilation optimization Rust is doing for "short" arrays? Compiled with rustc -C…
Guy Korland
  • 9,139
  • 14
  • 59
  • 106
184
votes
4 answers

How does Rust's 128-bit integer `i128` work on a 64-bit system?

Rust has 128-bit integers, these are denoted with the data type i128 (and u128 for unsigned ints): let a: i128 = 170141183460469231731687303715884105727; How does Rust make these i128 values work on a 64-bit system; e.g. how does it do arithmetic…
ruohola
  • 21,987
  • 6
  • 62
  • 97
130
votes
1 answer

When should inline be used in Rust?

Rust has an "inline" attribute that can be used in one of those three flavors: #[inline] #[inline(always)] #[inline(never)] When should they be used? In the Rust reference, we see an inline attributes section saying The compiler automatically…
WiSaGaN
  • 46,887
  • 10
  • 54
  • 88
33
votes
3 answers

What do the optimization levels `-Os` and `-Oz` do in rustc?

Executing rustc -C help shows (among other things): -C opt-level=val -- optimize with possible levels 0-3, s, or z The levels 0 to 3 are fairly intuitive, I think: the higher the level, the more aggressive optimizations will be performed.…
Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305
29
votes
1 answer

Can Rust optimise away the bit-wise copy during move of an object someday?

Consider the snippet struct Foo { dummy: [u8; 65536], } fn bar(foo: Foo) { println!("{:p}", &foo) } fn main() { let o = Foo { dummy: [42u8; 65536] }; println!("{:p}", &o); bar(o); } A typical result of the program…
WiSaGaN
  • 46,887
  • 10
  • 54
  • 88
29
votes
1 answer

Why does my code run slower when I remove bounds checks?

I'm writing a linear algebra library in Rust. I have a function to get a reference to a matrix cell at a given row and column. This function starts with a pair of assertions that the row and column are within bounds: #[inline(always)] pub fn…
Bradley Hardy
  • 765
  • 4
  • 14
26
votes
1 answer

Is there a way to get Rust to treat pointers as non-aliasing, so it can mark them as `noalias` for LLVM's optimizer?

The following example of pointer aliasing: pub unsafe fn f(a: *mut i32, b: *mut i32, x: *const i32) { *a = *x; *b = *x; } compiles into the following assembly (with -C opt-level=s): example::f: push rbp mov rbp, rsp …
Cornstalks
  • 37,137
  • 18
  • 79
  • 144
26
votes
1 answer

LLVM's integer types

The LLVM language specifies integer types as iN, where N is the bit-width of the integer, and ranges from 1 to 2^23-1 (According to: http://llvm.org/docs/LangRef.html#integer-type) I have 2 questions: When compiling a C program down to LLVM IR…
Ali J
  • 332
  • 1
  • 5
  • 8
21
votes
2 answers

How do I compile with "ffast-math"?

I'm trying to benchmark some Rust code, but I can't figure out how to set the "ffast-math" option. % rustc -C opt-level=3 -C llvm-args='-enable-unsafe-fp-math' unrolled.rs rustc: Unknown command line argument '-enable-unsafe-fp-math'. Try: 'rustc…
yong
  • 3,583
  • 16
  • 32
16
votes
4 answers

Why does this code generate much more assembly than equivalent C++/Clang?

I wrote a simple C++ function in order to check compiler optimization: bool f1(bool a, bool b) { return !a || (a && b); } After that I checked the equivalent in Rust: fn f1(a: bool, b: bool) -> bool { !a || (a && b) } I used godbolt to…
Mariusz Jaskółka
  • 4,137
  • 2
  • 21
  • 47
15
votes
1 answer

Why does LLVM appear to ignore Rust's assume intrinsic?

LLVM appears to ignore core::intrinsics::assume(..) calls. They do end up in the bytecode, but don't change the resulting machine code. For example take the following (nonsensical) code: pub fn one(xs: &mut Vec) { if let Some(x) = xs.pop()…
llogiq
  • 13,815
  • 8
  • 40
  • 72
15
votes
2 answers

LLVM opt mem2reg has no effect

I am currently playing around with LLVM and am trying to write a few optimizers to familiarize myself with opt and clang. I wrote a test.c file that is as follow: int foo(int aa, int bb, int cc){ int sum = aa + bb; return sum/cc; } I…
15
votes
1 answer

Why doesn't the Rust optimizer remove those useless instructions (tested on Godbolt Compiler Explorer)?

I wanted to take a look at the assembly output for a tiny Rust function: pub fn double(n: u8) -> u8 { n + n } I used the Godbolt Compiler Explorer to generate and view the assembly (with the -O flag, of course). It shows this…
Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305
1
2 3