For PR970:
Clean up handling of isFloatingPoint() and dealing with PackedType.
Patch by Gordon Henriksen!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33415 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index e8d5845..bf16327 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -499,32 +499,37 @@
   void visitInvoke(InvokeInst &I) { assert(0 && "TODO"); }
   void visitUnwind(UnwindInst &I) { assert(0 && "TODO"); }
 
-  void visitIntBinary(User &I, unsigned IntOp, unsigned VecOp);
-  void visitFPBinary(User &I, unsigned FPOp, unsigned VecOp);
+  void visitScalarBinary(User &I, unsigned OpCode);
+  void visitVectorBinary(User &I, unsigned OpCode);
+  void visitEitherBinary(User &I, unsigned ScalarOp, unsigned VectorOp);
   void visitShift(User &I, unsigned Opcode);
   void visitAdd(User &I) { 
-    if (I.getType()->isFloatingPoint())
-      visitFPBinary(I, ISD::FADD, ISD::VADD); 
+    if (isa<PackedType>(I.getType()))
+      visitVectorBinary(I, ISD::VADD);
+    else if (I.getType()->isFloatingPoint())
+      visitScalarBinary(I, ISD::FADD);
     else
-      visitIntBinary(I, ISD::ADD, ISD::VADD); 
+      visitScalarBinary(I, ISD::ADD);
   }
   void visitSub(User &I);
   void visitMul(User &I) {
-    if (I.getType()->isFloatingPoint()) 
-      visitFPBinary(I, ISD::FMUL, ISD::VMUL); 
+    if (isa<PackedType>(I.getType()))
+      visitVectorBinary(I, ISD::VMUL);
+    else if (I.getType()->isFloatingPoint())
+      visitScalarBinary(I, ISD::FMUL);
     else
-      visitIntBinary(I, ISD::MUL, ISD::VMUL); 
+      visitScalarBinary(I, ISD::MUL);
   }
-  void visitURem(User &I) { visitIntBinary(I, ISD::UREM, 0); }
-  void visitSRem(User &I) { visitIntBinary(I, ISD::SREM, 0); }
-  void visitFRem(User &I) { visitFPBinary (I, ISD::FREM, 0); }
-  void visitUDiv(User &I) { visitIntBinary(I, ISD::UDIV, ISD::VUDIV); }
-  void visitSDiv(User &I) { visitIntBinary(I, ISD::SDIV, ISD::VSDIV); }
-  void visitFDiv(User &I) { visitFPBinary (I, ISD::FDIV, ISD::VSDIV); }
-  void visitAnd(User &I) { visitIntBinary(I, ISD::AND, ISD::VAND); }
-  void visitOr (User &I) { visitIntBinary(I, ISD::OR,  ISD::VOR); }
-  void visitXor(User &I) { visitIntBinary(I, ISD::XOR, ISD::VXOR); }
-  void visitShl(User &I) { visitShift(I, ISD::SHL); }
+  void visitURem(User &I) { visitScalarBinary(I, ISD::UREM); }
+  void visitSRem(User &I) { visitScalarBinary(I, ISD::SREM); }
+  void visitFRem(User &I) { visitScalarBinary(I, ISD::FREM); }
+  void visitUDiv(User &I) { visitEitherBinary(I, ISD::UDIV, ISD::VUDIV); }
+  void visitSDiv(User &I) { visitEitherBinary(I, ISD::SDIV, ISD::VSDIV); }
+  void visitFDiv(User &I) { visitEitherBinary(I, ISD::FDIV, ISD::VSDIV); }
+  void visitAnd (User &I) { visitEitherBinary(I, ISD::AND,  ISD::VAND ); }
+  void visitOr  (User &I) { visitEitherBinary(I, ISD::OR,   ISD::VOR  ); }
+  void visitXor (User &I) { visitEitherBinary(I, ISD::XOR,  ISD::VXOR ); }
+  void visitShl (User &I) { visitShift(I, ISD::SHL); }
   void visitLShr(User &I) { visitShift(I, ISD::SRL); }
   void visitAShr(User &I) { visitShift(I, ISD::SRA); }
   void visitICmp(User &I);
@@ -1369,46 +1374,47 @@
 
 void SelectionDAGLowering::visitSub(User &I) {
   // -0.0 - X --> fneg
-  if (I.getType()->isFloatingPoint()) {
+  const Type *Ty = I.getType();
+  if (isa<PackedType>(Ty)) {
+    visitVectorBinary(I, ISD::VSUB);
+  } else if (Ty->isFloatingPoint()) {
     if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
       if (CFP->isExactlyValue(-0.0)) {
         SDOperand Op2 = getValue(I.getOperand(1));
         setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
         return;
       }
-    visitFPBinary(I, ISD::FSUB, ISD::VSUB);
+    visitScalarBinary(I, ISD::FSUB);
   } else 
-    visitIntBinary(I, ISD::SUB, ISD::VSUB);
+    visitScalarBinary(I, ISD::SUB);
 }
 
-void 
-SelectionDAGLowering::visitIntBinary(User &I, unsigned IntOp, unsigned VecOp) {
-  const Type *Ty = I.getType();
+void SelectionDAGLowering::visitScalarBinary(User &I, unsigned OpCode) {
   SDOperand Op1 = getValue(I.getOperand(0));
   SDOperand Op2 = getValue(I.getOperand(1));
-
-  if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
-    SDOperand Num = DAG.getConstant(PTy->getNumElements(), MVT::i32);
-    SDOperand Typ = DAG.getValueType(TLI.getValueType(PTy->getElementType()));
-    setValue(&I, DAG.getNode(VecOp, MVT::Vector, Op1, Op2, Num, Typ));
-  } else {
-    setValue(&I, DAG.getNode(IntOp, Op1.getValueType(), Op1, Op2));
-  }
+  
+  setValue(&I, DAG.getNode(OpCode, Op1.getValueType(), Op1, Op2));
 }
 
-void 
-SelectionDAGLowering::visitFPBinary(User &I, unsigned FPOp, unsigned VecOp) {
-  const Type *Ty = I.getType();
-  SDOperand Op1 = getValue(I.getOperand(0));
-  SDOperand Op2 = getValue(I.getOperand(1));
+void
+SelectionDAGLowering::visitVectorBinary(User &I, unsigned OpCode) {
+  assert(isa<PackedType>(I.getType()));
+  const PackedType *Ty = cast<PackedType>(I.getType());
+  SDOperand Typ = DAG.getValueType(TLI.getValueType(Ty->getElementType()));
 
-  if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
-    SDOperand Num = DAG.getConstant(PTy->getNumElements(), MVT::i32);
-    SDOperand Typ = DAG.getValueType(TLI.getValueType(PTy->getElementType()));
-    setValue(&I, DAG.getNode(VecOp, MVT::Vector, Op1, Op2, Num, Typ));
-  } else {
-    setValue(&I, DAG.getNode(FPOp, Op1.getValueType(), Op1, Op2));
-  }
+  setValue(&I, DAG.getNode(OpCode, MVT::Vector,
+                           getValue(I.getOperand(0)),
+                           getValue(I.getOperand(1)),
+                           DAG.getConstant(Ty->getNumElements(), MVT::i32),
+                           Typ));
+}
+
+void SelectionDAGLowering::visitEitherBinary(User &I, unsigned ScalarOp,
+                                             unsigned VectorOp) {
+  if (isa<PackedType>(I.getType()))
+    visitVectorBinary(I, VectorOp);
+  else
+    visitScalarBinary(I, ScalarOp);
 }
 
 void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {