[llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp

Chris Lattner lattner at cs.uiuc.edu
Sat Apr 1 17:38:41 PST 2006



Changes in directory llvm/lib/VMCore:

ConstantFolding.cpp updated: 1.84 -> 1.85
---
Log message:

Constant fold casts from things like <4 x int> -> <4 x uint>, likewise int<->fp.


---
Diffs of the changes:  (+108 -0)

 ConstantFolding.cpp |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 108 insertions(+)


Index: llvm/lib/VMCore/ConstantFolding.cpp
diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.84 llvm/lib/VMCore/ConstantFolding.cpp:1.85
--- llvm/lib/VMCore/ConstantFolding.cpp:1.84	Fri Mar 31 12:31:40 2006
+++ llvm/lib/VMCore/ConstantFolding.cpp	Sat Apr  1 19:38:28 2006
@@ -24,6 +24,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/MathExtras.h"
 #include <limits>
 #include <cmath>
 using namespace llvm;
@@ -621,6 +622,81 @@
   return S ? S : 8;  // Treat pointers at 8 bytes
 }
 
+/// CastConstantPacked - Convert the specified ConstantPacked node to the
+/// specified packed type.  At this point, we know that the elements of the
+/// input packed constant are all simple integer or FP values.
+static Constant *CastConstantPacked(ConstantPacked *CP,
+                                    const PackedType *DstTy) {
+  unsigned SrcNumElts = CP->getType()->getNumElements();
+  unsigned DstNumElts = DstTy->getNumElements();
+  const Type *SrcEltTy = CP->getType()->getElementType();
+  const Type *DstEltTy = DstTy->getElementType();
+  
+  // If both vectors have the same number of elements (thus, the elements
+  // are the same size), perform the conversion now.
+  if (SrcNumElts == DstNumElts) {
+    std::vector<Constant*> Result;
+    
+    // If the src and dest elements are both integers, just cast each one
+    // which will do the appropriate bit-convert.
+    if (SrcEltTy->isIntegral() && DstEltTy->isIntegral()) {
+      for (unsigned i = 0; i != SrcNumElts; ++i)
+        Result.push_back(ConstantExpr::getCast(CP->getOperand(i),
+                                               DstEltTy));
+      return ConstantPacked::get(Result);
+    }
+    
+    if (SrcEltTy->isIntegral()) {
+      // Otherwise, this is an int-to-fp cast.
+      assert(DstEltTy->isFloatingPoint());
+      if (DstEltTy->getTypeID() == Type::DoubleTyID) {
+        for (unsigned i = 0; i != SrcNumElts; ++i) {
+          double V =
+            BitsToDouble(cast<ConstantInt>(CP->getOperand(i))->getRawValue());
+          Result.push_back(ConstantFP::get(Type::DoubleTy, V));
+        }
+        return ConstantPacked::get(Result);
+      }
+      assert(DstEltTy == Type::FloatTy && "Unknown fp type!");
+      for (unsigned i = 0; i != SrcNumElts; ++i) {
+        float V =
+        BitsToFloat(cast<ConstantInt>(CP->getOperand(i))->getRawValue());
+        Result.push_back(ConstantFP::get(Type::FloatTy, V));
+      }
+      return ConstantPacked::get(Result);
+    }
+    
+    // Otherwise, this is an fp-to-int cast.
+    assert(SrcEltTy->isFloatingPoint() && DstEltTy->isIntegral());
+    
+    if (SrcEltTy->getTypeID() == Type::DoubleTyID) {
+      for (unsigned i = 0; i != SrcNumElts; ++i) {
+        uint64_t V =
+          DoubleToBits(cast<ConstantFP>(CP->getOperand(i))->getValue());
+        Constant *C = ConstantUInt::get(Type::ULongTy, V);
+        Result.push_back(ConstantExpr::getCast(C, DstEltTy));
+      }
+      return ConstantPacked::get(Result);
+    }
+
+    assert(SrcEltTy->getTypeID() == Type::FloatTyID);
+    for (unsigned i = 0; i != SrcNumElts; ++i) {
+      unsigned V = FloatToBits(cast<ConstantFP>(CP->getOperand(i))->getValue());
+      Constant *C = ConstantUInt::get(Type::UIntTy, V);
+      Result.push_back(ConstantExpr::getCast(C, DstEltTy));
+    }
+    return ConstantPacked::get(Result);
+  }
+  
+  // Otherwise, this is a cast that changes element count and size.  Handle
+  // casts which shrink the elements here.
+  
+  // FIXME: We need to know endianness to do this!
+  
+  return 0;
+}
+
+
 Constant *llvm::ConstantFoldCastInstruction(const Constant *V,
                                             const Type *DestTy) {
   if (V->getType() == DestTy) return (Constant*)V;
@@ -688,6 +764,38 @@
       if (ElTy == DPTy->getElementType())
         return ConstantExpr::getGetElementPtr(const_cast<Constant*>(V),IdxList);
     }
+      
+  // Handle casts from one packed constant to another.  We know that the src and
+  // dest type have the same size.
+  if (const PackedType *DestPTy = dyn_cast<PackedType>(DestTy)) {
+    if (const PackedType *SrcTy = dyn_cast<PackedType>(V->getType())) {
+      assert(DestPTy->getElementType()->getPrimitiveSizeInBits() * 
+                 DestPTy->getNumElements()  ==
+             SrcTy->getElementType()->getPrimitiveSizeInBits() * 
+             SrcTy->getNumElements() && "Not cast between same sized vectors!");
+      if (isa<ConstantAggregateZero>(V))
+        return Constant::getNullValue(DestTy);
+      if (isa<UndefValue>(V))
+        return UndefValue::get(DestTy);
+      if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(V)) {
+        // This is a cast from a ConstantPacked of one type to a ConstantPacked
+        // of another type.  Check to see if all elements of the input are
+        // simple.
+        bool AllSimpleConstants = true;
+        for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) {
+          if (!isa<ConstantInt>(CP->getOperand(i)) &&
+              !isa<ConstantFP>(CP->getOperand(i))) {
+            AllSimpleConstants = false;
+            break;
+          }
+        }
+            
+        // If all of the elements are simple constants, we can fold this.
+        if (AllSimpleConstants)
+          return CastConstantPacked(const_cast<ConstantPacked*>(CP), DestPTy);
+      }
+    }
+  }
 
   ConstRules &Rules = ConstRules::get(V, V);
 






More information about the llvm-commits mailing list