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
14
votes
2 answers

Can I force Rust to not optimize a single function?

I have a function where Rust's/LLVM's optimization fails and leads to a panic (in the release version), while the unoptimized code (debug version) just works fine. If I compare the generated assembly code, I can not even grasp an idea what the…
Matthias
  • 8,018
  • 2
  • 27
  • 53
13
votes
2 answers

C ABI with LLVM

I've got a compiler written with LLVM and I'm looking to up my ABI compliance. For example, I've found it hard to actually find specification documents for C ABI on Windows x86 or Linux. And the ones I have found explain it in terms of RAX/EAX/etc,…
Puppy
  • 144,682
  • 38
  • 256
  • 465
12
votes
1 answer

Can compilers (specifically rustc) really simplify triangle-summation to avoid a loop? How?

On page 322 of Programming Rust by Blandy and Orendorff is this claim: ...Rust...recognizes that there's a simpler way to sum the numbers from one to n: the sum is always equal to n * (n+1) / 2. This is of course a fairly well-known equivalence,…
Kyle Strand
  • 15,941
  • 8
  • 72
  • 167
11
votes
1 answer

Why empty functions aren't removed as dead code in LLVM IR?

Starting with this simple C program: void nothing(void) {} int main() { int i; for (i = 0; i < 10; ++i) { nothing(); } return 0; } My passes output as follows: Note: IR statements are in Green. ; Function Attrs: nounwind readnone ssp…
Ahmed Ghoneim
  • 6,834
  • 9
  • 49
  • 79
10
votes
3 answers

Why does LLVM allocate a redundant variable?

Here's a simple C file with an enum definition and a main function: enum days {MON, TUE, WED, THU}; int main() { enum days d; d = WED; return 0; } It transpiles to the following LLVM IR: define dso_local i32 @main() #0 { %1 = alloca…
macleginn
  • 321
  • 2
  • 10
10
votes
1 answer

Why does clang produce inefficient asm with -O0 (for this simple floating point sum)?

I am disassembling this code on llvm clang Apple LLVM version 8.0.0 (clang-800.0.42.1): int main() { float a=0.151234; float b=0.2; float c=a+b; printf("%f", c); } I compiled with no -O specifications, but I also tried with -O0…
Stefano Borini
  • 138,652
  • 96
  • 297
  • 431
10
votes
1 answer

Why can the Rust compiler not optimize away the Err arm of Box::downcast?

I have a Box and I know the underlying type so I want to optimize away the test in Box::downcast() (source). First I tried with std::hint::unreachable_unchecked(): pub unsafe fn downcast() -> Box { let value = any(); if let…
Tim Diekmann
  • 7,755
  • 11
  • 41
  • 69
9
votes
1 answer

Is signed integer overflow in safe Rust in release mode considered as undefined behavior?

Rust treats signed integer overflow differently in debug and release mode. When it happens, Rust panics in debug mode while silently performs two's complement wrapping in release mode. As far as I know, C/C++ treats signed integer overflow as…
Zhiyao
  • 4,152
  • 2
  • 12
  • 21
9
votes
3 answers

Which integer operations have higher performance alternate methods in Rust?

When writing integer functions in Rust which will run millions of times (think pixel processing), it's useful to use operations with the highest performance - similar to C/C++. While the reference manual explains changes in behavior, it's not always…
ideasman42
  • 42,413
  • 44
  • 197
  • 320
7
votes
1 answer

Why isn't there a branch prediction failure penalty in this Rust code?

I've written this very simple Rust function: fn iterate(nums: &Box<[i32]>) -> i32 { let mut total = 0; let len = nums.len(); for i in 0..len { if nums[i] > 0 { total += nums[i]; } else { total -=…
5
votes
1 answer

Setting a non-default rounding mode with Rust inline asm isn't respected by the LLVM optimizer?

I am working on a Rust crate which changes the rounding mode (+inf, -inf, nearest, or truncate). The functions that change the rounding mode are written using inline assembly: fn upward() { let cw: u32 = 0; unsafe { asm!("stmxcsr $0; …
4
votes
1 answer

Why does clang emit a 32-bit float ps instruction for the absolute value of a 64-bit double?

Why is clang turning fabs(double) into vandps instead of vandpd (like GCC does)? Example from Compiler Explorer: #include double float_abs(double x) { return fabs(x); } clang 12.0.1 -std=gnu++11 -Wall -O3 -march=znver3 .LCPI0_0: …
soc
  • 27,983
  • 20
  • 111
  • 215
4
votes
4 answers

How to prevent function calls from being optimized away?

How can I ensure that a function with no side effects gets executed and doesn't get optimized away in stable Rust? Is there an attribute combination I could use, or must I call another function with side effects? In the case where a function call is…
Doe
  • 585
  • 5
  • 19
4
votes
1 answer

LLVM use of carry and zero flags

I'm starting to read LLVM docs and IR documentation. In common architectures, an asm cmp instruction "result" value is -at least- 3 bits long, let's say the first bit is the SIGN flag, the second bit is the CARRY flag and the third bit is the ZERO…
Lucio M. Tato
  • 5,639
  • 2
  • 31
  • 30
3
votes
0 answers

disable use of cmov in clang

From the command line it is possible to tell clang to disable use of some features, for example -mno-mmx or -mno-popcnt. However, while cmov is a feature tracked by llvm, there is no -mno-cmov for x86 processors (although you can disable…
PluckyBird
  • 131
  • 2