patch-r262261-llvm-r198281-sparc.diff revision 269012
1Pull in r198281 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3  [SparcV9]: Custom lower UMULO/SMULO so that the arguments are send to __multi3() in correct order.
4
5Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7Index: lib/Target/Sparc/SparcISelLowering.cpp
8===================================================================
9--- lib/Target/Sparc/SparcISelLowering.cpp
10+++ lib/Target/Sparc/SparcISelLowering.cpp
11@@ -1525,6 +1525,9 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
12     setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
13     setOperationAction(ISD::MULHU,     MVT::i64, Expand);
14     setOperationAction(ISD::MULHS,     MVT::i64, Expand);
15+
16+    setOperationAction(ISD::UMULO,     MVT::i64, Custom);
17+    setOperationAction(ISD::SMULO,     MVT::i64, Custom);
18   }
19 
20   // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
21@@ -2673,6 +2676,53 @@ static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op
22   return DAG.getMergeValues(Ops, 2, dl);
23 }
24 
25+// Custom lower UMULO/SMULO for SPARC. This code is similar to ExpandNode()
26+// in LegalizeDAG.cpp except the order of arguments to the library function.
27+static SDValue LowerUMULO_SMULO(SDValue Op, SelectionDAG &DAG,
28+                                const SparcTargetLowering &TLI)
29+{
30+  unsigned opcode = Op.getOpcode();
31+  assert((opcode == ISD::UMULO || opcode == ISD::SMULO) && "Invalid Opcode.");
32+
33+  bool isSigned = (opcode == ISD::SMULO);
34+  EVT VT = MVT::i64;
35+  EVT WideVT = MVT::i128;
36+  SDLoc dl(Op);
37+  SDValue LHS = Op.getOperand(0);
38+
39+  if (LHS.getValueType() != VT)
40+    return Op;
41+
42+  SDValue ShiftAmt = DAG.getConstant(63, VT);
43+
44+  SDValue RHS = Op.getOperand(1);
45+  SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, LHS, ShiftAmt);
46+  SDValue HiRHS = DAG.getNode(ISD::SRA, dl, MVT::i64, RHS, ShiftAmt);
47+  SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
48+
49+  SDValue MulResult = TLI.makeLibCall(DAG,
50+                                      RTLIB::MUL_I128, WideVT,
51+                                      Args, 4, isSigned, dl).first;
52+  SDValue BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT,
53+                                   MulResult, DAG.getIntPtrConstant(0));
54+  SDValue TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT,
55+                                MulResult, DAG.getIntPtrConstant(1));
56+  if (isSigned) {
57+    SDValue Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, ShiftAmt);
58+    TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, Tmp1, ISD::SETNE);
59+  } else {
60+    TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, DAG.getConstant(0, VT),
61+                           ISD::SETNE);
62+  }
63+  // MulResult is a node with an illegal type. Because such things are not
64+  // generally permitted during this phase of legalization, delete the
65+  // node. The above EXTRACT_ELEMENT nodes should have been folded.
66+  DAG.DeleteNode(MulResult.getNode());
67+
68+  SDValue Ops[2] = { BottomHalf, TopHalf } ;
69+  return DAG.getMergeValues(Ops, 2, dl);
70+}
71+
72 SDValue SparcTargetLowering::
73 LowerOperation(SDValue Op, SelectionDAG &DAG) const {
74 
75@@ -2726,6 +2776,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
76   case ISD::ADDE:
77   case ISD::SUBC:
78   case ISD::SUBE:               return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
79+  case ISD::UMULO:
80+  case ISD::SMULO:              return LowerUMULO_SMULO(Op, DAG, *this);
81   }
82 }
83 
84Index: test/CodeGen/SPARC/64cond.ll
85===================================================================
86--- test/CodeGen/SPARC/64cond.ll
87+++ test/CodeGen/SPARC/64cond.ll
88@@ -111,6 +111,11 @@ entry:
89 }
90 
91 ; CHECK-LABEL: setcc_resultty
92+; CHECK-DAG:       srax %i0, 63, %o0
93+; CHECK-DAG:       or %g0, %i0, %o1
94+; CHECK-DAG:       or %g0, 0, %o2
95+; CHECK-DAG:       or %g0, 32, %o3
96+; CHECK-DAG:       call __multi3
97 ; CHECK:       cmp
98 ; CHECK:       movne %xcc, 1, [[R:%[gilo][0-7]]]
99 ; CHECK:       or [[R]], %i1, %i0
100