Teach DAGCombiner how to fold a SIGN_EXTEND_INREG of a BUILD_VECTOR of
[oota-llvm.git] / lib / CodeGen / SelectionDAG / DAGCombiner.cpp
index f8728b6d603093a5cfef20a3a710f43373cf964c..68d0521e7630a9a76686ea740d33b617d2793994 100644 (file)
@@ -5511,6 +5511,29 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
                          BSwap, N1);
   }
 
+  // Fold a sext_inreg of a build_vector of ConstantSDNodes or undefs
+  // into a build_vector.
+  if (ISD::isBuildVectorOfConstantSDNodes(N0.getNode())) {
+    SmallVector<SDValue, 8> Elts;
+    unsigned NumElts = N0->getNumOperands();
+    unsigned ShAmt = VTBits - EVTBits;
+
+    for (unsigned i = 0; i != NumElts; ++i) {
+      SDValue Op = N0->getOperand(i);
+      if (Op->getOpcode() == ISD::UNDEF) {
+        Elts.push_back(Op);
+        continue;
+      }
+
+      ConstantSDNode *CurrentND = cast<ConstantSDNode>(Op);
+      const APInt &C = CurrentND->getAPIntValue();
+      Elts.push_back(DAG.getConstant(C.shl(ShAmt).ashr(ShAmt),
+                                     Op.getValueType()));
+    }
+
+    return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), VT, &Elts[0], NumElts);
+  }
+
   return SDValue();
 }