llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.11k stars 12.01k forks source link

PowerPC `fp128` -> `half` uses `__trunctfhf2` but should be `__trunckfhf2` #98126

Open tgross35 opened 4 months ago

tgross35 commented 4 months ago
define half @trunckfhf(fp128 %a) unnamed_addr {
start:
  %_0 = fptrunc fp128 %a to half
  ret half %_0
}

Output on powerpc64-unknown-linux-gnu:

trunckfhf:                              # @trunckfhf
        .quad   .Lfunc_begin0
        .quad   .TOC.@tocbase
        .quad   0
.Lfunc_begin0:
        mflr 0
        stdu 1, -112(1)
        std 0, 128(1)
        bl __trunctfhf2
        nop
        clrldi  3, 3, 48
        bl __gnu_h2f_ieee
        nop
        addi 1, 1, 112
        ld 0, 16(1)
        mtlr 0
        blr
        .long   0
        .quad   0

Note that this emits __trunctfhf2. According to https://gcc.gnu.org/wiki/Ieee128PowerPC (second table in section 2.2), tf is for whatever long double is in C, which on PPC is usually IBM double double, but kf is always for IEEE binary128. So it seems like this should instead emit a symbol named __trunckfhf2.

This would be consistent with other fptrunc operations for fp128, which lower to kf symbols (__trunckfsf2, __trunckfdf2).

There is more discussion at this thread https://github.com/llvm/llvm-project/issues/92866. Neither GCC nor LLVM provide this symbol yet in libgcc/compiler-rt, but I don't think that should block correcting the symbol name.

Tested at compiler explorer using 19.0.0git. Link: https://llvm.godbolt.org/z/7MosczYcr

llvmbot commented 4 months ago

@llvm/issue-subscribers-backend-powerpc

Author: Trevor Gross (tgross35)

```llvm define half @trunckfhf(fp128 %a) unnamed_addr { start: %_0 = fptrunc fp128 %a to half ret half %_0 } ``` Output on `powerpc64-unknown-linux-gnu`: ```asm trunckfhf: # @trunckfhf .quad .Lfunc_begin0 .quad .TOC.@tocbase .quad 0 .Lfunc_begin0: mflr 0 stdu 1, -112(1) std 0, 128(1) bl __trunctfhf2 nop clrldi 3, 3, 48 bl __gnu_h2f_ieee nop addi 1, 1, 112 ld 0, 16(1) mtlr 0 blr .long 0 .quad 0 ``` Note that this emits `__trunctfhf2`. According to https://gcc.gnu.org/wiki/Ieee128PowerPC (second table in section 2.2), `tf` is for whatever `long double` is in C, which on PPC is usually IBM double double, but `kf` is always for IEEE `binary128`. So it seems like this should instead emit a symbol named `__trunckfhf2`. This would be consistent with other fptrunc operations for `fp128`, which lower to `kf` symbols (`__trunckfsf2`, `__trunckfdf2`). There is more discussion at this thread https://github.com/llvm/llvm-project/issues/92866. Neither GCC nor LLVM provide this symbol yet in libgcc/compiler-rt, but I don't think that should block correcting the symbol name. Tested at compiler explorer using `19.0.0git`. Link: https://llvm.godbolt.org/z/7MosczYcr