CellSPU:
(a) Slight rethink on i64 zero/sign/any extend code - use a shuffle to
    directly zero-extend i32 to i64, but use rotates and shifts for
    sign extension. Also ensure unified register consistency.
(b) Add new test harness for i64 operations: i64ops.ll


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59970 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp
index 2a6607c..0b95474 100644
--- a/lib/Target/CellSPU/SPUISelLowering.cpp
+++ b/lib/Target/CellSPU/SPUISelLowering.cpp
@@ -2363,16 +2363,27 @@
 
     SDValue PromoteScalar =
             DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
-    SDValue RotQuad =
-            DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, Op0VecVT,
-                        PromoteScalar, DAG.getConstant(4, MVT::i32));
 
     if (Opc != ISD::SIGN_EXTEND) {
+      // Use a shuffle to zero extend the i32 to i64 directly:
+      SDValue shufMask =
+              DAG.getNode(ISD::BUILD_VECTOR, Op0VecVT,
+                          DAG.getConstant(0x80808080, MVT::i32),
+                          DAG.getConstant(0x00010203, MVT::i32),
+                          DAG.getConstant(0x80808080, MVT::i32),
+                          DAG.getConstant(0x08090a0b, MVT::i32));
+      SDValue zextShuffle =
+              DAG.getNode(SPUISD::SHUFB, Op0VecVT,
+                          PromoteScalar, PromoteScalar, shufMask);
+
       return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
-                         DAG.getNode(ISD::BIT_CONVERT, VecVT, RotQuad));
+                         DAG.getNode(ISD::BIT_CONVERT, VecVT, zextShuffle));
     } else {
       // SPU has no "rotate quadword and replicate bit 0" (i.e. rotate/shift
       // right and propagate the sign bit) instruction.
+      SDValue RotQuad =
+              DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, Op0VecVT,
+                          PromoteScalar, DAG.getConstant(4, MVT::i32));
       SDValue SignQuad =
               DAG.getNode(SPUISD::VEC_SRA, Op0VecVT,
                           PromoteScalar, DAG.getConstant(32, MVT::i32));