mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-23 20:16:06 +00:00

Adding wide integer emulation support for `arith.fpto*i` operations. As the other emulated operations, the upper and lower `N` bits of the `i2N` integer result are emitted separately. For the unsigned case we use the following emulation ```c // example is 64 -> 32 bit emulation, but the implementation is generalized to any 2N -> N case const double TWO_POW_N = (uint_64_t(1) << N); // 2^N, N is the bitwidth of the widest int supported // f is a floating-point value representing the input of the fptoui op. uint32_t hi = (uint32_t)(f / TWO_POW_N); // Truncates the division result uint32_t lo = (uint32_t)(f - hi * TWO_POW_N); // Subtracts to get the lower bits. ``` For the signed case, we defer the emulation of the absolute value to `fptoui` and handle the sign: ``` fptosi(fp) = sign(fp) * fptoui(abs(fp)) ``` The edge cases of `NaNs, +-inf` and overflows/underflows are undefined behaviour and the resulting numbers are the combination of the lower bitwidth UB values. These operations also propagate poison values. Signed-off-by: Ege Beysel <beysel@roofline.ai>