[LLVMdev] troubles with llvm-gcc 4.0 and APFloat on X86_64
Dietmar Ebner
ebner at complang.tuwien.ac.at
Sat Oct 20 04:22:56 PDT 2007
hi,
Dale Johannesen wrote:
> On Oct 19, 2007, at 7:23 AM, Dietmar Ebner wrote:
>> i'm trying to make some experiments with the ARM backend (llvm 2.1)
>> and
>> therefore built an arm-softfloat-linux-gnu toolchain on x86_64 linux.
>>
>> however, the llvm-gcc frontend seems to cause troubles with single
>> precision floating point values, i.e., they are not converted
>> correctly
>> to the particular target format (double precision works as expected).
>
> I haven't seen this problem. You say the frontend; to check,
>
> llvm-gcc -O0 -S -emit-llvm file.c -o file.ll
>
> produces an invalid constant in the .ll file? Can you give an example?
here's what i get for the following example:
#include <stdio.h>
int main(int argc, char *argv[])
{
float f = 0.6;
printf("hello world: %f / %f\n", f, 0.6);
}
------------------------------------------
; ModuleID = 'test.c'
target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:12
8:128-a0:0:64-s0:0:64"
target triple = "arm-softfloat-linux-gnu"
@.str = internal constant [22 x i8] c"hello world: %f / %f\0A\00"
; <[22 x i8]*> [#uses=1]
define i32 @main(i32 %argc, i8** %argv) {
entry:
%argc_addr = alloca i32 ; <i32*> [#uses=1]
%argv_addr = alloca i8** ; <i8***> [#uses=1]
%retval = alloca i32, align 4 ; <i32*> [#uses=1]
%f = alloca float, align 4 ; <float*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store i32 %argc, i32* %argc_addr
store i8** %argv, i8*** %argv_addr
store float 0x4000000040000000, float* %f, align 4
%tmp = load float* %f, align 4 ; <float> [#uses=1]
%tmp1 = fpext float %tmp to double ; <double>
[#uses=1]
%tmp2 = getelementptr [22 x i8]* @.str, i32 0, i32 0
; <i8*> [#uses=1]
%tmp3 = call i32 (i8* noalias , ...)* @printf( i8* %tmp2
noalias , double %tmp1, double 0x333333333FE33333
) ; <i32> [#uses=0]
br label %return
return: ; preds = %entry
%retval4 = load i32* %retval ; <i32> [#uses=1]
ret i32 %retval4
}
declare i32 @printf(i8* noalias , ...)
------------------------------------------
which gives me the following when compiled and executed:
hello world: 2.000000 / 0.600000
i've configured llvm-gcc (RELEASE_21) as follows:
$ llvm-arm-gcc -v
Using built-in specs.
Target: arm-softfloat-linux-gnu
Configured with: /nfs/a5/ebner/dev/official/llvm-gcc/configure
--prefix=/nfstmp/util/arm-softfloat-linux-gnu/
--program-prefix=llvm-arm-
--enable-llvm=/nfs/a5/ebner/dev/cross/arm-softfloat-linux/llvm
--enable-checking --target=arm-softfloat-linux-gnu --disable-shared
--disable-nls --disable-threads --with-float=soft --enable-languages=c
Thread model: single
i've applied a small patch (see below) to link the ieee754 softfloat
library into libgcc.
>> it seems the problem is related to the following piece of code taken
>> from APFloat.cpp:1836 (called from ConvertREAL_CST)
>> APFloat::APFloat(float f) {
>> APInt api = APInt(32, 0);
>> initFromAPInt(api.floatToBits(f));
>> }
>>
>> i guess the floatToBits call will return the wrong half word since
>> ints
>> are 4, but float and double are both 8 byte on x86_64 (but i'm not yet
>> sure).
>
> I'm pretty sure float is 4 everywhere; that wouldn't be it.
sure! sorry for the noise
-
dietmar
Index: gcc/config/arm/linux-elf.h
===================================================================
--- gcc/config/arm/linux-elf.h (revision 42922)
+++ gcc/config/arm/linux-elf.h (working copy)
@@ -56,7 +56,7 @@
%{shared:-lc} \
%{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat}
-lgcc"
+/* #define LIBGCC_SPEC "%{msoft-float:-lfloat}
%{mfloat-abi=soft*:-lfloat} -lgcc" */
/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
Index: gcc/config/arm/t-linux
===================================================================
--- gcc/config/arm/t-linux (revision 42922)
+++ gcc/config/arm/t-linux (working copy)
@@ -4,7 +4,10 @@
LIBGCC2_DEBUG_CFLAGS = -g0
LIB1ASMSRC = arm/lib1funcs.asm
-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \
+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi
_fixunsdfsi \
+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
+ _fixsfsi _fixunssfsi
# MULTILIB_OPTIONS = mhard-float/msoft-float
# MULTILIB_DIRNAMES = hard-float soft-float
More information about the llvm-dev
mailing list