]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r198281-sparc.diff
1 Pull 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
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
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);
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  
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:
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