-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Open
Description
Starting with llvm 14.0.0 there is a regression in PowerPC backend due to compiler-rt code resulting in libc function calls regardless of the -nostdlib
/ -ffreestanding
flags.
One such example is __fixunsdfdi
(compiler-rt/lib/builtins/fixunsdfdi.c), which is implemented as follows:
COMPILER_RT_ABI du_int __fixunsdfdi(double a) {
if (a <= 0.0)
return 0;
su_int high = a / 4294967296.f; // a / 0x1p32f;
su_int low = a - (double)high * 4294967296.f; // high * 0x1p32f;
return ((du_int)high << 32) | low;
}
The problematic part can be shortened to the following code snippet:
unsigned func(double a, double high) {
return a - high * 4294967296.f;
}
Upon compiling with clang -O3 -target powerpc-gnu-linux -msoft-float -mcpu=e500mc -O3 -nostdlib
the following code is generated:
func(double, double): # @func(double, double)
mflr 0
stw 0, 4(1)
stwu 1, -16(1)
mr 7, 6
mr 8, 5
mr 9, 4
mr 10, 3
lis 5, -15888
li 6, 0
mr 3, 8
mr 4, 7
mr 7, 10
mr 8, 9
bl fma
bl __fixunsdfsi
lwz 0, 20(1)
addi 1, 1, 16
mtlr 0
blr
fma
is not a function provided by compiler-rt builtins and thus should not be generated here. There is no issue with 13.0.1:
func(double, double): # @func(double, double)
mflr 0
stw 0, 4(1)
stwu 1, -32(1)
mr 7, 6
mr 8, 5
stw 29, 20(1) # 4-byte Folded Spill
mr 29, 3
stw 30, 24(1) # 4-byte Folded Spill
mr 30, 4
lis 5, -15888
li 6, 0
mr 3, 8
mr 4, 7
bl __muldf3
mr 5, 3
mr 6, 4
mr 3, 29
mr 4, 30
bl __adddf3
bl __fixunsdfsi
lwz 30, 24(1) # 4-byte Folded Reload
lwz 29, 20(1) # 4-byte Folded Reload
lwz 0, 36(1)
addi 1, 1, 32
mtlr 0
blr
CC @tstellar, this may need to be fixed in some 14.0.x release.