Replace inferred getCast(V,Ty) calls with more strict variants.
[oota-llvm.git] / lib / VMCore / ConstantFold.cpp
index 97a55cbcf7eb5af4141bb4e6b363409d5cbc8240..170df73272330a34d597348d7e739fc81578d758 100644 (file)
@@ -743,8 +743,7 @@ static Constant *CastConstantPacked(ConstantPacked *CP,
         (SrcEltTy->isFloatingPoint() && DstEltTy->isFloatingPoint())) {
       for (unsigned i = 0; i != SrcNumElts; ++i)
         Result.push_back(
-          ConstantExpr::getCast(Instruction::BitCast, CP->getOperand(i), 
-                                DstEltTy));
+          ConstantExpr::getBitCast(CP->getOperand(i), DstEltTy));
       return ConstantPacked::get(Result);
     }
     
@@ -828,10 +827,6 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
                                             const Type *DestTy) {
   const Type *SrcTy = V->getType();
 
-  // Handle some simple cases
-  if (SrcTy == DestTy) 
-    return (Constant*)V; // no-op cast
-
   if (isa<UndefValue>(V))
     return UndefValue::get(DestTy);
 
@@ -901,6 +896,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
       return ConstantIntegral::get(DestTy, CI->getZExtValue());
     return 0;
   case Instruction::BitCast:
+    if (SrcTy == DestTy) return (Constant*)V; // no-op cast
+    
     // Check to see if we are casting a pointer to an aggregate to a pointer to
     // the first element.  If so, return the appropriate GEP instruction.
     if (const PointerType *PTy = dyn_cast<PointerType>(V->getType()))
@@ -960,18 +957,39 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
       }
     }
 
-    // Handle sign conversion for integer no-op casts. We need to cast the
-    // value to the correct signedness before we try to cast it to the
-    // destination type. Be careful to do this only for integer types.
-    if (isa<ConstantIntegral>(V) && SrcTy->isInteger()) {
-      if (SrcTy->isSigned())
-        V = ConstantInt::get(SrcTy->getUnsignedVersion(), 
-                             cast<ConstantIntegral>(V)->getZExtValue());
-       else 
-        V = ConstantInt::get(SrcTy->getSignedVersion(), 
-                             cast<ConstantIntegral>(V)->getSExtValue());
+    // Finally, implement bitcast folding now.   The code below doesn't handle
+    // bitcast right.
+    if (isa<ConstantPointerNull>(V))  // ptr->ptr cast.
+      return ConstantPointerNull::get(cast<PointerType>(DestTy));
+
+    // Handle integral constant input.
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+      // Integral -> Integral, must be changing sign.
+      if (DestTy->isIntegral())
+        return ConstantInt::get(DestTy, CI->getZExtValue());
+
+      if (DestTy->isFloatingPoint()) {
+        if (DestTy == Type::FloatTy)
+          return ConstantFP::get(DestTy, BitsToFloat(CI->getZExtValue()));
+        assert(DestTy == Type::DoubleTy && "Unknown FP type!");
+        return ConstantFP::get(DestTy, BitsToDouble(CI->getZExtValue()));
+      }
+      // Otherwise, can't fold this (packed?)
+      return 0;
     }
-    break;
+      
+    // Handle ConstantFP input.
+    if (const ConstantFP *FP = dyn_cast<ConstantFP>(V)) {
+      // FP -> Integral.
+      if (DestTy->isIntegral()) {
+        if (DestTy == Type::IntTy || DestTy == Type::UIntTy)
+          return ConstantInt::get(DestTy, FloatToBits(FP->getValue()));
+        assert((DestTy == Type::LongTy || DestTy == Type::ULongTy) 
+               && "Incorrect integer  type for bitcast!");
+        return ConstantInt::get(DestTy, DoubleToBits(FP->getValue()));
+      }
+    }
+    return 0;
   default:
     assert(!"Invalid CE CastInst opcode");
     break;
@@ -1129,11 +1147,11 @@ static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) {
   // Ok, we have two differing integer indices.  Sign extend them to be the same
   // type.  Long is always big enough, so we use it.
   if (C1->getType() != Type::LongTy && C1->getType() != Type::ULongTy)
-    C1 = ConstantExpr::getSignExtend(C1, Type::LongTy);
+    C1 = ConstantExpr::getSExt(C1, Type::LongTy);
   else
     C1 = ConstantExpr::getBitCast(C1, Type::LongTy);
   if (C2->getType() != Type::LongTy && C1->getType() != Type::ULongTy)
-    C2 = ConstantExpr::getSignExtend(C2, Type::LongTy);
+    C2 = ConstantExpr::getSExt(C2, Type::LongTy);
   else
     C2 = ConstantExpr::getBitCast(C2, Type::LongTy);
 
@@ -1156,7 +1174,7 @@ static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) {
 /// evaluateRelation - This function determines if there is anything we can
 /// decide about the two constants provided.  This doesn't need to handle simple
 /// things like integer comparisons, but should instead handle ConstantExprs
-/// and GlobalValuess.  If we can determine that the two constants have a
+/// and GlobalValues.  If we can determine that the two constants have a
 /// particular relation to each other, we should return the corresponding SetCC
 /// code, otherwise return Instruction::BinaryOpsEnd.
 ///
@@ -1653,7 +1671,7 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C,
         R = ConstantExpr::getSExtOrBitCast(R, Idx0->getType());
         R = ConstantExpr::getMul(R, Idx0); // signed multiply
         // R is a signed integer, C is the GEP pointer so -> IntToPtr
-        return ConstantExpr::getCast(Instruction::IntToPtr, R, C->getType());
+        return ConstantExpr::getIntToPtr(R, C->getType());
       }
     }
   }