1 Pull in r198281 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [SparcV9]: Custom lower UMULO/SMULO so that the arguments are send to __multi3() in correct order.
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
7 Index: 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);
16 + setOperationAction(ISD::UMULO, MVT::i64, Custom);
17 + setOperationAction(ISD::SMULO, MVT::i64, Custom);
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);
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)
30 + unsigned opcode = Op.getOpcode();
31 + assert((opcode == ISD::UMULO || opcode == ISD::SMULO) && "Invalid Opcode.");
33 + bool isSigned = (opcode == ISD::SMULO);
35 + EVT WideVT = MVT::i128;
37 + SDValue LHS = Op.getOperand(0);
39 + if (LHS.getValueType() != VT)
42 + SDValue ShiftAmt = DAG.getConstant(63, VT);
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 };
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));
57 + SDValue Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, ShiftAmt);
58 + TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, Tmp1, ISD::SETNE);
60 + TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, DAG.getConstant(0, VT),
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());
68 + SDValue Ops[2] = { BottomHalf, TopHalf } ;
69 + return DAG.getMergeValues(Ops, 2, dl);
72 SDValue SparcTargetLowering::
73 LowerOperation(SDValue Op, SelectionDAG &DAG) const {
75 @@ -2726,6 +2776,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
78 case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
80 + case ISD::SMULO: return LowerUMULO_SMULO(Op, DAG, *this);
84 Index: test/CodeGen/SPARC/64cond.ll
85 ===================================================================
86 --- test/CodeGen/SPARC/64cond.ll
87 +++ test/CodeGen/SPARC/64cond.ll
88 @@ -111,6 +111,11 @@ entry:
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
98 ; CHECK: movne %xcc, 1, [[R:%[gilo][0-7]]]
99 ; CHECK: or [[R]], %i1, %i0