[llvm-commits] [llvm] r131530 - in /llvm/trunk: lib/VMCore/Instructions.cpp unittests/VMCore/InstructionsTest.cpp

Duncan Sands baldrick at free.fr
Wed May 18 00:13:41 PDT 2011


Author: baldrick
Date: Wed May 18 02:13:41 2011
New Revision: 131530

URL: http://llvm.org/viewvc/llvm-project?rev=131530&view=rev
Log:
Teach getCastOpcode about element-by-element vector casts.  For example, "trunc"
can be used to turn a <4 x i64> into a <4 x i32> but getCastOpcode would assert
if you passed these types to it.  Note that this strictly extends the previous
functionality: if getCastOpcode previously accepted two vector types (i.e. didn't
assert) then it still will and returns the same opcode (BitCast).  That's because
before it would only accept vectors with the same bitwidth, and the new code only
touches vectors with the same length.  However if two vectors have both the same
bitwidth and the same length then their element types have the same bitwidth, so
the new logic will return BitCast as before.

Modified:
    llvm/trunk/lib/VMCore/Instructions.cpp
    llvm/trunk/unittests/VMCore/InstructionsTest.cpp

Modified: llvm/trunk/lib/VMCore/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=131530&r1=131529&r2=131530&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Instructions.cpp (original)
+++ llvm/trunk/lib/VMCore/Instructions.cpp Wed May 18 02:13:41 2011
@@ -2254,6 +2254,14 @@
   if (SrcTy == DestTy)
     return true;
 
+  if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
+    if (const 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->getScalarSizeInBits();   // 0 for ptr
   unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
@@ -2322,14 +2330,27 @@
 Instruction::CastOps
 CastInst::getCastOpcode(
   const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
-  // Get the bit sizes, we'll need these
   const Type *SrcTy = Src->getType();
-  unsigned SrcBits = SrcTy->getScalarSizeInBits();   // 0 for ptr
-  unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
 
   assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
          "Only first class types are castable!");
 
+  if (SrcTy == DestTy)
+    return BitCast;
+
+  if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
+    if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
+      if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
+        // An element by element cast.  Find the appropriate opcode based on the
+        // element types.
+        SrcTy = SrcVecTy->getElementType();
+        DestTy = DestVecTy->getElementType();
+      }
+
+  // Get the bit sizes, we'll need these
+  unsigned SrcBits = SrcTy->getScalarSizeInBits();   // 0 for ptr
+  unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
+
   // Run through the possibilities ...
   if (DestTy->isIntegerTy()) {                      // Casting to integral
     if (SrcTy->isIntegerTy()) {                     // Casting from integral
@@ -2384,7 +2405,7 @@
     if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
       assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
              "Casting vector to vector of different widths");
-      SrcPTy = NULL;
+      (void)SrcPTy;
       return BitCast;                             // vector -> vector
     } else if (DestPTy->getBitWidth() == SrcBits) {
       return BitCast;                               // float/int -> vector

Modified: llvm/trunk/unittests/VMCore/InstructionsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/InstructionsTest.cpp?rev=131530&r1=131529&r2=131530&view=diff
==============================================================================
--- llvm/trunk/unittests/VMCore/InstructionsTest.cpp (original)
+++ llvm/trunk/unittests/VMCore/InstructionsTest.cpp Wed May 18 02:13:41 2011
@@ -114,11 +114,19 @@
   const Type* Int8Ty = Type::getInt8Ty(C);
   const Type* Int64Ty = Type::getInt64Ty(C);
   const Type* V8x8Ty = VectorType::get(Int8Ty, 8);
+  const Type* V8x64Ty = VectorType::get(Int64Ty, 8);
   const Type* X86MMXTy = Type::getX86_MMXTy(C);
 
+  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::getCastOpcode(c64, true, V8x8Ty, true), CastInst::Trunc);
+  EXPECT_EQ(CastInst::getCastOpcode(c8, true, V8x64Ty, true), CastInst::SExt);
 }
 
 }  // end anonymous namespace





More information about the llvm-commits mailing list