Repository navigation
LLVM miscompiles consecutive half operations by using too much precision on several backends #97975
Description
Activity
@llvm/issue-subscribers-backend-powerpc
Author: None (beetrees)
Details
Consider the following IR: ```llvm define half @f(half %a, half %b, half %c) { %d = fadd half %a, %b %e = fadd half %d, %c ret half %e } ```On backends without native
halfsupport, LLVM generally lowershalfby converting tofloat, performing the desired operation, and then converting back tohalf. For this to be a valid lowering, a conversion back tof16must occur after each operation, otherwise the excess precision offloatwill affect the result. For example65504.0 + 65504.0 + -65504.0equals infinity if each operation is done athalfprecision, but will result in65504.0if the intermediate value is not rounded to ahalfbut instead kept as afloat. This excess runtime precision can lead to miscompilations similar to #89885.However, it appears that on several backends LLVM will fail to round the intermediate result of consecutive
halfoperations, leading to these kind of bugs. I'm filing this as a single issue rather than a separate issue for each backend as I believe this is an issue with LLVM's default handling ofhalfoperations rather than a problem in any specific backend (for instance, AFAIK the only backend-specific code LoongArch has for handlinghalfwas added in #94456).By inspecting the assembly LLVM emits, I've discovered that at least the following backends appear to be affected (in brackets are a specific target triple that I've checked):
- AVR (
avr-unknown-unknown) - Hexagon (
hexagon-unknown-linux-musl) - LoongArch (
loongarch64-unknown-linux-gnu) - M68k (
m68k-unknown-linux-gnu) - MIPS (
mips64el-unknown-linux-gnuabi64) - MSP430 (
msp430-none-elf) - PowerPC (
powerpc64le-unknown-linux-gnu) - SPARC (
sparc64-unknown-linux-gnu) - WASM (
wasm32-unknown-wasi): Already reported in Onwasm32,halfoperation results aren't correctly rounded between each operation #96437
I also noticed that 32-bit ARM has this problem in LLVM 18 but not on the
mainbranch. Looking through the issue tracker, it seems it's likely that this was fixed by #80440.- AVR (
@llvm/issue-subscribers-backend-hexagon
Author: None (beetrees)
Details
Consider the following IR: ```llvm define half @f(half %a, half %b, half %c) { %d = fadd half %a, %b %e = fadd half %d, %c ret half %e } ```On backends without native
halfsupport, LLVM generally lowershalfby converting tofloat, performing the desired operation, and then converting back tohalf. For this to be a valid lowering, a conversion back tof16must occur after each operation, otherwise the excess precision offloatwill affect the result. For example65504.0 + 65504.0 + -65504.0equals infinity if each operation is done athalfprecision, but will result in65504.0if the intermediate value is not rounded to ahalfbut instead kept as afloat. This excess runtime precision can lead to miscompilations similar to #89885.However, it appears that on several backends LLVM will fail to round the intermediate result of consecutive
halfoperations, leading to these kind of bugs. I'm filing this as a single issue rather than a separate issue for each backend as I believe this is an issue with LLVM's default handling ofhalfoperations rather than a problem in any specific backend (for instance, AFAIK the only backend-specific code LoongArch has for handlinghalfwas added in #94456).By inspecting the assembly LLVM emits, I've discovered that at least the following backends appear to be affected (in brackets are a specific target triple that I've checked):
- AVR (
avr-unknown-unknown) - Hexagon (
hexagon-unknown-linux-musl) - LoongArch (
loongarch64-unknown-linux-gnu) - M68k (
m68k-unknown-linux-gnu) - MIPS (
mips64el-unknown-linux-gnuabi64) - MSP430 (
msp430-none-elf) - PowerPC (
powerpc64le-unknown-linux-gnu) - SPARC (
sparc64-unknown-linux-gnu) - WASM (
wasm32-unknown-wasi): Already reported in Onwasm32,halfoperation results aren't correctly rounded between each operation #96437
I also noticed that 32-bit ARM has this problem in LLVM 18 but not on the
mainbranch. Looking through the issue tracker, it seems it's likely that this was fixed by #80440.- AVR (
132 remaining items
- added a commit that references this issue
on Jul 21, 2026 - added 9 commits that reference this issue
on Jul 30, 2026 - added a commit that references this issue
on Oct 7, 2026
Consider the following IR:
On backends without native
halfsupport, LLVM generally lowershalfby converting tofloat, performing the desired operation, and then converting back tohalf. For this to be a valid lowering, a conversion back tof16must occur after each operation, otherwise the excess precision offloatwill affect the result. For example65504.0 + 65504.0 + -65504.0equals infinity if each operation is done athalfprecision, but will result in65504.0if the intermediate value is not rounded to ahalfbut instead kept as afloat. This excess runtime precision can lead to miscompilations similar to #89885.However, it appears that on several backends LLVM will fail to round the intermediate result of consecutive
halfoperations, leading to these kind of bugs. I'm filing this as a single issue rather than a separate issue for each backend as I believe this is an issue with LLVM's default handling ofhalfoperations rather than a problem in any specific backend (for instance, AFAIK the only backend-specific code LoongArch has for handlinghalfwas added in #94456).By inspecting the assembly LLVM emits, I've discovered that at least the following backends appear to be affected (in brackets are a specific target triple that I've checked):
avr-unknown-unknown): Fixed by [AVR] Changehalfto usesoftPromoteHalfType#152783csky-unknown-linux-gnuabiv2)hexagon-unknown-linux-musl): Fixed by [HEXAGON] Add support to lower "FREEZE a half(f16)" instruction on Hexagon and fix the isel-buildvector-v2f16.ll assertion #130977loongarch64-unknown-linux-gnu): Fixed by [loongarch][DAG][FREEZE] Fix crash when FREEZE a half(f16) type on loongarch #107791m68k-unknown-linux-gnu)mips64el-unknown-linux-gnuabi64): Fixed by [MIPS] Use softPromoteHalf legalization for fp16 rather than PromoteFloat #110199msp430-none-elf)powerpc64le-unknown-linux-gnu): Fixed by [PowerPC] Changehalfto use soft promotion rather thanPromoteFloat#152632sparc64-unknown-linux-gnu): Fixed by [SPARC] Changehalfto use soft promotion rather thanPromoteFloat#152727wasm32-unknown-wasi): Already reported in Onwasm32,halfoperation results aren't correctly rounded between each operation #96437, fixed by [WebAssembly] Changehalfto use soft promotion rather thanPromoteFloat#152833xtensa-none-elf)I also noticed that 32-bit ARM has this problem in LLVM 18 but not on the
mainbranch. Looking through the issue tracker, it seems it's likely that this was fixed by #80440.Related to #97981.