[llvm-commits] [llvm] r57956 - in /llvm/trunk: lib/Target/CBackend/CBackend.cpp test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll

Chris Lattner sabre at nondot.org
Tue Oct 21 21:53:17 PDT 2008


Author: lattner
Date: Tue Oct 21 23:53:16 2008
New Revision: 57956

URL: http://llvm.org/viewvc/llvm-project?rev=57956&view=rev
Log:
Fix PR2907 by digging through constant expressions to find FP constants that
are their operands.

Added:
    llvm/trunk/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll
Modified:
    llvm/trunk/lib/Target/CBackend/CBackend.cpp

Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=57956&r1=57955&r2=57956&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Tue Oct 21 23:53:16 2008
@@ -88,12 +88,15 @@
     std::map<const ConstantFP *, unsigned> FPConstantMap;
     std::set<Function*> intrinsicPrototypesAlreadyGenerated;
     std::set<const Argument*> ByValParams;
+    unsigned FPCounter;
 
   public:
     static char ID;
     explicit CWriter(raw_ostream &o)
       : FunctionPass(&ID), Out(o), IL(0), Mang(0), LI(0), 
-        TheModule(0), TAsm(0), TD(0) {}
+        TheModule(0), TAsm(0), TD(0) {
+      FPCounter = 0;
+    }
 
     virtual const char *getPassName() const { return "C backend"; }
 
@@ -181,6 +184,7 @@
     void printModuleTypes(const TypeSymbolTable &ST);
     void printContainedStructs(const Type *Ty, std::set<const Type *> &);
     void printFloatingPointConstants(Function &F);
+    void printFloatingPointConstants(const Constant *C);
     void printFunctionSignature(const Function *F, bool Prototype);
 
     void printFunction(Function &);
@@ -834,10 +838,10 @@
 static bool isFPCSafeToPrint(const ConstantFP *CFP) {
   bool ignored;
   // Do long doubles in hex for now.
-  if (CFP->getType()!=Type::FloatTy && CFP->getType()!=Type::DoubleTy)
+  if (CFP->getType() != Type::FloatTy && CFP->getType() != Type::DoubleTy)
     return false;
   APFloat APF = APFloat(CFP->getValueAPF());  // copy
-  if (CFP->getType()==Type::FloatTy)
+  if (CFP->getType() == Type::FloatTy)
     APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
 #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A
   char Buffer[100];
@@ -2029,51 +2033,68 @@
   // the precision of the printed form, unless the printed form preserves
   // precision.
   //
-  static unsigned FPCounter = 0;
   for (constant_iterator I = constant_begin(&F), E = constant_end(&F);
        I != E; ++I)
-    if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
-      if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe.
-          !FPConstantMap.count(FPC)) {
-        FPConstantMap[FPC] = FPCounter;  // Number the FP constants
-
-        if (FPC->getType() == Type::DoubleTy) {
-          double Val = FPC->getValueAPF().convertToDouble();
-          uint64_t i = FPC->getValueAPF().bitcastToAPInt().getZExtValue();
-          Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
-              << " = 0x" << utohexstr(i)
-              << "ULL;    /* " << Val << " */\n";
-        } else if (FPC->getType() == Type::FloatTy) {
-          float Val = FPC->getValueAPF().convertToFloat();
-          uint32_t i = (uint32_t)FPC->getValueAPF().bitcastToAPInt().
-                                    getZExtValue();
-          Out << "static const ConstantFloatTy FPConstant" << FPCounter++
-              << " = 0x" << utohexstr(i)
-              << "U;    /* " << Val << " */\n";
-        } else if (FPC->getType() == Type::X86_FP80Ty) {
-          // api needed to prevent premature destruction
-          APInt api = FPC->getValueAPF().bitcastToAPInt();
-          const uint64_t *p = api.getRawData();
-          Out << "static const ConstantFP80Ty FPConstant" << FPCounter++
-              << " = { 0x"
-              << utohexstr((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16)
-              << "ULL, 0x" << utohexstr((uint16_t)(p[0] >> 48)) << ",{0,0,0}"
-              << "}; /* Long double constant */\n";
-        } else if (FPC->getType() == Type::PPC_FP128Ty) {
-          APInt api = FPC->getValueAPF().bitcastToAPInt();
-          const uint64_t *p = api.getRawData();
-          Out << "static const ConstantFP128Ty FPConstant" << FPCounter++
-              << " = { 0x"
-              << utohexstr(p[0]) << ", 0x" << utohexstr(p[1])
-              << "}; /* Long double constant */\n";
-
-        } else
-          assert(0 && "Unknown float type!");
-      }
+    printFloatingPointConstants(*I);
 
   Out << '\n';
 }
 
+void CWriter::printFloatingPointConstants(const Constant *C) {
+  // If this is a constant expression, recursively check for constant fp values.
+  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+    for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
+      printFloatingPointConstants(CE->getOperand(i));
+    return;
+  }
+    
+  // Otherwise, check for a FP constant that we need to print.
+  const ConstantFP *FPC = dyn_cast<ConstantFP>(C);
+  if (FPC == 0 ||
+      // Do not put in FPConstantMap if safe.
+      isFPCSafeToPrint(FPC) ||
+      // Already printed this constant?
+      FPConstantMap.count(FPC))
+    return;
+
+  FPConstantMap[FPC] = FPCounter;  // Number the FP constants
+  
+  if (FPC->getType() == Type::DoubleTy) {
+    double Val = FPC->getValueAPF().convertToDouble();
+    uint64_t i = FPC->getValueAPF().bitcastToAPInt().getZExtValue();
+    Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
+    << " = 0x" << utohexstr(i)
+    << "ULL;    /* " << Val << " */\n";
+  } else if (FPC->getType() == Type::FloatTy) {
+    float Val = FPC->getValueAPF().convertToFloat();
+    uint32_t i = (uint32_t)FPC->getValueAPF().bitcastToAPInt().
+    getZExtValue();
+    Out << "static const ConstantFloatTy FPConstant" << FPCounter++
+    << " = 0x" << utohexstr(i)
+    << "U;    /* " << Val << " */\n";
+  } else if (FPC->getType() == Type::X86_FP80Ty) {
+    // api needed to prevent premature destruction
+    APInt api = FPC->getValueAPF().bitcastToAPInt();
+    const uint64_t *p = api.getRawData();
+    Out << "static const ConstantFP80Ty FPConstant" << FPCounter++
+    << " = { 0x"
+    << utohexstr((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16)
+    << "ULL, 0x" << utohexstr((uint16_t)(p[0] >> 48)) << ",{0,0,0}"
+    << "}; /* Long double constant */\n";
+  } else if (FPC->getType() == Type::PPC_FP128Ty) {
+    APInt api = FPC->getValueAPF().bitcastToAPInt();
+    const uint64_t *p = api.getRawData();
+    Out << "static const ConstantFP128Ty FPConstant" << FPCounter++
+    << " = { 0x"
+    << utohexstr(p[0]) << ", 0x" << utohexstr(p[1])
+    << "}; /* Long double constant */\n";
+    
+  } else {
+    assert(0 && "Unknown float type!");
+  }
+}
+
+
 
 /// printSymbolTable - Run through symbol table looking for type names.  If a
 /// type name is found, emit its declaration...

Added: llvm/trunk/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll?rev=57956&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll (added)
+++ llvm/trunk/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll Tue Oct 21 23:53:16 2008
@@ -0,0 +1,29 @@
+; RUN: llvm-as < %s | llc -march=c
+; PR2907
+target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128"
+target triple = "powerpc-apple-darwin9.5"
+	%"struct.Point<0>" = type { %"struct.Tensor<1,0>" }
+	%"struct.QGauss2<1>" = type { %"struct.Quadrature<0>" }
+	%"struct.Quadrature<0>" = type { %struct.Subscriptor, i32, %"struct.std::vector<Point<0>,std::allocator<Point<0> > >", %"struct.std::vector<double,std::allocator<double> >" }
+	%struct.Subscriptor = type { i32 (...)**, i32, %"struct.std::type_info"* }
+	%"struct.Tensor<1,0>" = type { [1 x double] }
+	%"struct.std::_Vector_base<Point<0>,std::allocator<Point<0> > >" = type { %"struct.std::_Vector_base<Point<0>,std::allocator<Point<0> > >::_Vector_impl" }
+	%"struct.std::_Vector_base<Point<0>,std::allocator<Point<0> > >::_Vector_impl" = type { %"struct.Point<0>"*, %"struct.Point<0>"*, %"struct.Point<0>"* }
+	%"struct.std::_Vector_base<double,std::allocator<double> >" = type { %"struct.std::_Vector_base<double,std::allocator<double> >::_Vector_impl" }
+	%"struct.std::_Vector_base<double,std::allocator<double> >::_Vector_impl" = type { double*, double*, double* }
+	%"struct.std::type_info" = type { i32 (...)**, i8* }
+	%"struct.std::vector<Point<0>,std::allocator<Point<0> > >" = type { %"struct.std::_Vector_base<Point<0>,std::allocator<Point<0> > >" }
+	%"struct.std::vector<double,std::allocator<double> >" = type { %"struct.std::_Vector_base<double,std::allocator<double> >" }
+
+define fastcc void @_ZN6QGaussILi1EEC1Ej(%"struct.QGauss2<1>"* %this, i32 %n) {
+entry:
+	br label %bb4
+
+bb4:		; preds = %bb5.split, %bb4, %entry
+	%0 = fcmp ogt ppc_fp128 0xM00000000000000000000000000000000, select (i1 fcmp olt (ppc_fp128 fpext (double 0x3C447AE147AE147B to ppc_fp128), ppc_fp128 mul (ppc_fp128 0xM00000000000000010000000000000000, ppc_fp128 0xM40140000000000000000000000000000)), ppc_fp128 mul (ppc_fp128 0xM00000000000000010000000000000000, ppc_fp128 0xM40140000000000000000000000000000), ppc_fp128 fpext (double 0x3C447AE147AE147B to ppc_fp128))		; <i1> [#uses=1]
+	br i1 %0, label %bb4, label %bb5.split
+
+bb5.split:		; preds = %bb4
+	%1 = getelementptr double* null, i32 0		; <double*> [#uses=0]
+	br label %bb4
+}





More information about the llvm-commits mailing list