Revert "Remove isCastable since nothing uses it now"
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 30 Jul 2013 22:02:14 +0000 (22:02 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 30 Jul 2013 22:02:14 +0000 (22:02 +0000)
Apparently dragonegg uses it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187454 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/InstrTypes.h
lib/IR/Instructions.cpp
unittests/IR/InstructionsTest.cpp

index e32af766ca803f183a7c05107db210c51b3a1892..e12bb03a403f09a89fa31f157cdb92c9caebb770 100644 (file)
@@ -209,7 +209,7 @@ public:
     BO->setHasNoSignedWrap(true);
     return BO;
   }
-
+  
   static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
                                    const Twine &Name = "") {
     BinaryOperator *BO = Create(Opc, V1, V2, Name);
@@ -228,7 +228,7 @@ public:
     BO->setHasNoUnsignedWrap(true);
     return BO;
   }
-
+  
   static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
                                      const Twine &Name = "") {
     BinaryOperator *BO = Create(Opc, V1, V2, Name);
@@ -247,7 +247,7 @@ public:
     BO->setIsExact(true);
     return BO;
   }
-
+  
 #define DEFINE_HELPERS(OPC, NUWNSWEXACT)                                     \
   static BinaryOperator *Create ## NUWNSWEXACT ## OPC                        \
            (Value *V1, Value *V2, const Twine &Name = "") {                  \
@@ -261,7 +261,7 @@ public:
            (Value *V1, Value *V2, const Twine &Name, Instruction *I) {       \
     return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, I);         \
   }
-
+  
   DEFINE_HELPERS(Add, NSW)  // CreateNSWAdd
   DEFINE_HELPERS(Add, NUW)  // CreateNUWAdd
   DEFINE_HELPERS(Sub, NSW)  // CreateNSWSub
@@ -277,7 +277,7 @@ public:
   DEFINE_HELPERS(LShr, Exact)  // CreateExactLShr
 
 #undef DEFINE_HELPERS
-
+  
   /// Helper functions to construct and inspect unary operations (NEG and NOT)
   /// via binary operators SUB and XOR:
   ///
@@ -525,6 +525,12 @@ public:
     BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
   );
 
+  /// @brief Check whether it is valid to call getCastOpcode for these types.
+  static bool isCastable(
+    Type *SrcTy, ///< The Type from which the value should be cast.
+    Type *DestTy ///< The Type to which the value should be cast.
+  );
+
   /// @brief Check whether a bitcast between these types is valid
   static bool isBitCastable(
     Type *SrcTy, ///< The Type from which the value should be cast.
index f2c669131ddddfad191aee005faea6548a2ed2f2..665fe66ccc39fbc8b49855350e07012777a4a2a1 100644 (file)
@@ -2454,6 +2454,69 @@ CastInst *CastInst::CreateFPCast(Value *C, Type *Ty,
   return Create(opcode, C, Ty, Name, InsertAtEnd);
 }
 
+// Check whether it is valid to call getCastOpcode for these types.
+// This routine must be kept in sync with getCastOpcode.
+bool CastInst::isCastable(Type *SrcTy, Type *DestTy) {
+  if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType())
+    return false;
+
+  if (SrcTy == DestTy)
+    return true;
+
+  if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
+    if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
+      if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
+        // An element by element cast.  Valid if casting the elements is valid.
+        SrcTy = SrcVecTy->getElementType();
+        DestTy = DestVecTy->getElementType();
+      }
+
+  // Get the bit sizes, we'll need these
+  unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr
+  unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
+
+  // Run through the possibilities ...
+  if (DestTy->isIntegerTy()) {               // Casting to integral
+    if (SrcTy->isIntegerTy()) {                // Casting from integral
+        return true;
+    } else if (SrcTy->isFloatingPointTy()) {   // Casting from floating pt
+      return true;
+    } else if (SrcTy->isVectorTy()) {          // Casting from vector
+      return DestBits == SrcBits;
+    } else {                                   // Casting from something else
+      return SrcTy->isPointerTy();
+    }
+  } else if (DestTy->isFloatingPointTy()) {  // Casting to floating pt
+    if (SrcTy->isIntegerTy()) {                // Casting from integral
+      return true;
+    } else if (SrcTy->isFloatingPointTy()) {   // Casting from floating pt
+      return true;
+    } else if (SrcTy->isVectorTy()) {          // Casting from vector
+      return DestBits == SrcBits;
+    } else {                                   // Casting from something else
+      return false;
+    }
+  } else if (DestTy->isVectorTy()) {         // Casting to vector
+    return DestBits == SrcBits;
+  } else if (DestTy->isPointerTy()) {        // Casting to pointer
+    if (SrcTy->isPointerTy()) {                // Casting from pointer
+      return true;
+    } else if (SrcTy->isIntegerTy()) {         // Casting from integral
+      return true;
+    } else {                                   // Casting from something else
+      return false;
+    }
+  } else if (DestTy->isX86_MMXTy()) {
+    if (SrcTy->isVectorTy()) {
+      return DestBits == SrcBits;       // 64-bit vector to MMX
+    } else {
+      return false;
+    }
+  } else {                                   // Casting to something else
+    return false;
+  }
+}
+
 bool CastInst::isBitCastable(Type *SrcTy, Type *DestTy) {
   if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType())
     return false;
index 8f4f1945d50cb3b064ba14b851a3ff680e892e8d..34d662dcb343d8321128f068746e4cdc838ead52 100644 (file)
@@ -149,6 +149,11 @@ TEST(InstructionsTest, CastInst) {
   const Constant* c8 = Constant::getNullValue(V8x8Ty);
   const Constant* c64 = Constant::getNullValue(V8x64Ty);
 
+  EXPECT_TRUE(CastInst::isCastable(V8x8Ty, X86MMXTy));
+  EXPECT_TRUE(CastInst::isCastable(X86MMXTy, V8x8Ty));
+  EXPECT_FALSE(CastInst::isCastable(Int64Ty, X86MMXTy));
+  EXPECT_TRUE(CastInst::isCastable(V8x64Ty, V8x8Ty));
+  EXPECT_TRUE(CastInst::isCastable(V8x8Ty, V8x64Ty));
   EXPECT_EQ(CastInst::Trunc, CastInst::getCastOpcode(c64, true, V8x8Ty, true));
   EXPECT_EQ(CastInst::SExt, CastInst::getCastOpcode(c8, true, V8x64Ty, true));