Issue 174935
Summary [RISC-V] Knowledge of integer range leads to suboptimal codegen for instructions that could use sign-extended imm12
Labels new issue
Assignees
Reporter Arnavion
    ```c
#include <stdint.h>

uint32_t foo(uint32_t arg) {
    // __builtin_assume(arg <= 0x1FFFF);
    return arg & 0xFFFFFBFF;
}
```

Compiled with `-O3`, clang correctly emits this as:

```asm
foo:
        andi     a0, a0, -1025   ; 0xBFF
 ret
```

... taking advantage of the sign-extension of `0xBFF` into `0xFFFFFBFF`.

But when the `__builtin_assume` is uncommented, clang now knows that `arg` only has the lower 17 bits set. It then uses this information to optimize the `&` RHS into the 17-bit mask `0x1FBFF`. The downside of this is that constructing the value `0x1FBFF` in RISC-V then requires a `lui; addi` sequence that must then be `and`ed with the arg.

```asm
foo:
        lui     a1, 32           ; 0x2000
        addi a1, a1, -1025    ; 0x2000 - 0x401 = 0x1FBFF
        and     a0, a0, a1
 ret
```

This ends up being worse than if clang had not done the integer range optimization.

(In my original Rust code, the integer range knowledge comes implicitly from the calculations that produce `arg`, so I cannot simply make LLVM forget that knowledge.)

---

clang version 22.0.0git (https://github.com/llvm/llvm-project.git dc43062638852201464b7b3e8a7e716c4f23e47e)
Target: x86_64-unknown-linux-gnu
Thread model: posix

("clang trunk" in godbolt.)
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to