[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