[LLVMbugs] [Bug 3503] New: cbe: emits incorrect code for double/long double
bugzilla-daemon at cs.uiuc.edu
bugzilla-daemon at cs.uiuc.edu
Sat Feb 7 11:27:48 PST 2009
http://llvm.org/bugs/show_bug.cgi?id=3503
Summary: cbe: emits incorrect code for double/long double
Product: new-bugs
Version: unspecified
Platform: PC
OS/Version: Linux
Status: NEW
Severity: normal
Priority: P2
Component: new bugs
AssignedTo: unassignedbugs at nondot.org
ReportedBy: edwintorok at gmail.com
CC: llvmbugs at cs.uiuc.edu
On x86-64 linux using the 2.5 prerelease branch:
$ llc -march=c x.bc
$ gcc x.cbe.c -lm
x.cbe.c:116: warning: conflicting types for built-in function ‘malloc’
x.cbe.c:122: warning: conflicting types for built-in function ‘powl’
x.cbe.c: In function ‘foo’:
x.cbe.c:152: warning: function called through a non-compatible type
x.cbe.c:152: note: if this code is reached, the program will abort
x.cbe.c: In function ‘main’:
x.cbe.c:157: warning: return type of ‘main’ is not ‘int’
$ ./a.out
Illegal instruction
Other backends (JIT, LLC) work just fine.
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-unknown-linux-gnu"
define i32 @foo(double %a) nounwind readonly {
entry:
%0 = fpext double %a to x86_fp80 ; <x86_fp80> [#uses=3]
%1 = tail call x86_fp80 @llvm.sqrt.f80(x86_fp80 %0) ;
<x86_fp80> [#uses=1]
%2 = tail call double @llvm.sqrt.f64(double %a) ; <double>
[#uses=1]
%3 = fpext double %2 to x86_fp80 ; <x86_fp80> [#uses=1]
%4 = add x86_fp80 %1, %3 ; <x86_fp80> [#uses=1]
%5 = tail call double @llvm.pow.f64(double %a, double %a)
; <double> [#uses=1]
%6 = fpext double %5 to x86_fp80 ; <x86_fp80> [#uses=1]
%7 = add x86_fp80 %4, %6 ; <x86_fp80> [#uses=1]
%8 = tail call x86_fp80 @llvm.pow.f80(x86_fp80 %0, x86_fp80 %0)
; <x86_fp80> [#uses=1]
%9 = add x86_fp80 %7, %8 ; <x86_fp80> [#uses=1]
%10 = fptosi x86_fp80 %9 to i32 ; <i32> [#uses=1]
ret i32 %10
}
declare x86_fp80 @llvm.sqrt.f80(x86_fp80) nounwind readonly
declare double @llvm.sqrt.f64(double) nounwind readonly
declare double @llvm.pow.f64(double, double) nounwind readonly
declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) nounwind readonly
define i32 @main() nounwind readonly {
entry:
%0 = tail call i32 @foo(double 4.000000e+00) nounwind ; <i32>
[#uses=1]
ret i32 %0
Here is x.cbe.c, you'll notice that the prototype for powl is wrong,
causing gcc to emit code that will abort:
/* Provide Declarations */
#include <stdarg.h>
#include <setjmp.h>
/* get a declaration for alloca */
#if defined(__CYGWIN__) || defined(__MINGW32__)
#define alloca(x) __builtin_alloca((x))
#define _alloca(x) __builtin_alloca((x))
#elif defined(__APPLE__)
extern void *__builtin_alloca(unsigned long);
#define alloca(x) __builtin_alloca(x)
#define longjmp _longjmp
#define setjmp _setjmp
#elif defined(__sun__)
#if defined(__sparcv9)
extern void *__builtin_alloca(unsigned long);
#else
extern void *__builtin_alloca(unsigned int);
#endif
#define alloca(x) __builtin_alloca(x)
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ||
defined(__DragonFly__)
#define alloca(x) __builtin_alloca(x)
#elif defined(_MSC_VER)
#define inline _inline
#define alloca(x) _alloca(x)
#else
#include <alloca.h>
#endif
#ifndef __GNUC__ /* Can only support "linkonce" vars with GCC */
#define __attribute__(X)
#endif
#if defined(__GNUC__) && defined(__APPLE_CC__)
#define __EXTERNAL_WEAK__ __attribute__((weak_import))
#elif defined(__GNUC__)
#define __EXTERNAL_WEAK__ __attribute__((weak))
#else
#define __EXTERNAL_WEAK__
#endif
#if defined(__GNUC__) && defined(__APPLE_CC__)
#define __ATTRIBUTE_WEAK__
#elif defined(__GNUC__)
#define __ATTRIBUTE_WEAK__ __attribute__((weak))
#else
#define __ATTRIBUTE_WEAK__
#endif
#if defined(__GNUC__)
#define __HIDDEN__ __attribute__((visibility("hidden")))
#endif
#ifdef __GNUC__
#define LLVM_NAN(NanStr) __builtin_nan(NanStr) /* Double */
#define LLVM_NANF(NanStr) __builtin_nanf(NanStr) /* Float */
#define LLVM_NANS(NanStr) __builtin_nans(NanStr) /* Double */
#define LLVM_NANSF(NanStr) __builtin_nansf(NanStr) /* Float */
#define LLVM_INF __builtin_inf() /* Double */
#define LLVM_INFF __builtin_inff() /* Float */
#define LLVM_PREFETCH(addr,rw,locality) __builtin_prefetch(addr,rw,locality)
#define __ATTRIBUTE_CTOR__ __attribute__((constructor))
#define __ATTRIBUTE_DTOR__ __attribute__((destructor))
#define LLVM_ASM __asm__
#else
#define LLVM_NAN(NanStr) ((double)0.0) /* Double */
#define LLVM_NANF(NanStr) 0.0F /* Float */
#define LLVM_NANS(NanStr) ((double)0.0) /* Double */
#define LLVM_NANSF(NanStr) 0.0F /* Float */
#define LLVM_INF ((double)0.0) /* Double */
#define LLVM_INFF 0.0F /* Float */
#define LLVM_PREFETCH(addr,rw,locality) /* PREFETCH */
#define __ATTRIBUTE_CTOR__
#define __ATTRIBUTE_DTOR__
#define LLVM_ASM(X)
#endif
#if __GNUC__ < 4 /* Old GCC's, or compilers not GCC */
#define __builtin_stack_save() 0 /* not implemented */
#define __builtin_stack_restore(X) /* noop */
#endif
#if __GNUC__ && __LP64__ /* 128-bit integer types */
typedef int __attribute__((mode(TI))) llvmInt128;
typedef unsigned __attribute__((mode(TI))) llvmUInt128;
#endif
#define CODE_FOR_MAIN() /* Any target-specific code for main()*/
#ifndef __cplusplus
typedef unsigned char bool;
#endif
/* Support for floating point constants */
typedef unsigned long long ConstantDoubleTy;
typedef unsigned int ConstantFloatTy;
typedef struct { unsigned long long f1; unsigned short f2; unsigned short
pad[3]; } ConstantFP80Ty;
typedef struct { unsigned long long f1; unsigned long long f2; }
ConstantFP128Ty;
/* Global Declarations */
/* Helper union for bitcasts */
typedef union {
unsigned int Int32;
unsigned long long Int64;
float Float;
double Double;
} llvmBitCastUnion;
/* Function Declarations */
double fmod(double, double);
float fmodf(float, float);
long double fmodl(long double, long double);
unsigned int foo(double llvm_cbe_a);
unsigned int main(void);
unsigned char *malloc();
void free(unsigned char *);
void abort(void);
long double sqrtl(long double );
double sqrt(double );
double pow(double , double );
double powl(double , double );
/* Function Bodies */
static inline int llvm_fcmp_ord(double X, double Y) { return X == X && Y == Y;
}
static inline int llvm_fcmp_uno(double X, double Y) { return X != X || Y != Y;
}
static inline int llvm_fcmp_ueq(double X, double Y) { return X == Y ||
llvm_fcmp_uno(X, Y); }
static inline int llvm_fcmp_une(double X, double Y) { return X != Y; }
static inline int llvm_fcmp_ult(double X, double Y) { return X < Y ||
llvm_fcmp_uno(X, Y); }
static inline int llvm_fcmp_ugt(double X, double Y) { return X > Y ||
llvm_fcmp_uno(X, Y); }
static inline int llvm_fcmp_ule(double X, double Y) { return X <= Y ||
llvm_fcmp_uno(X, Y); }
static inline int llvm_fcmp_uge(double X, double Y) { return X >= Y ||
llvm_fcmp_uno(X, Y); }
static inline int llvm_fcmp_oeq(double X, double Y) { return X == Y ; }
static inline int llvm_fcmp_one(double X, double Y) { return X != Y &&
llvm_fcmp_ord(X, Y); }
static inline int llvm_fcmp_olt(double X, double Y) { return X < Y ; }
static inline int llvm_fcmp_ogt(double X, double Y) { return X > Y ; }
static inline int llvm_fcmp_ole(double X, double Y) { return X <= Y ; }
static inline int llvm_fcmp_oge(double X, double Y) { return X >= Y ; }
unsigned int foo(double llvm_cbe_a) {
long double ltmp_0_1;
long double ltmp_1_1;
double ltmp_2_2;
double ltmp_3_2;
long double ltmp_4_1;
ltmp_0_1 = ((long double )llvm_cbe_a);
ltmp_1_1 = sqrtl(ltmp_0_1);
ltmp_2_2 = sqrt(llvm_cbe_a);
ltmp_3_2 = pow(llvm_cbe_a, llvm_cbe_a);
ltmp_4_1 = ((long double (*) (long double , long double
))(void*)powl)(ltmp_0_1, ltmp_0_1);
return (((signed int )(((ltmp_1_1 + (((long double )ltmp_2_2))) + (((long
double )ltmp_3_2))) + ltmp_4_1)));
}
unsigned int main(void) {
unsigned int ltmp_5_3;
CODE_FOR_MAIN();
ltmp_5_3 = /*tail*/ foo(0x1p+2);
return ltmp_5_3;
}
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list