diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff new file mode 100644 index 0000000..0af21f4 --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff @@ -0,0 +1,99 @@ +Pull in r198281 from upstream llvm trunk (by Venkatraman Govindaraju): + + [SparcV9]: Custom lower UMULO/SMULO so that the arguments are send to __multi3() in correct order. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: lib/Target/Sparc/SparcISelLowering.cpp +=================================================================== +--- lib/Target/Sparc/SparcISelLowering.cpp ++++ lib/Target/Sparc/SparcISelLowering.cpp +@@ -1525,6 +1525,9 @@ SparcTargetLowering::SparcTargetLowering(TargetMac + setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); + setOperationAction(ISD::MULHU, MVT::i64, Expand); + setOperationAction(ISD::MULHS, MVT::i64, Expand); ++ ++ setOperationAction(ISD::UMULO, MVT::i64, Custom); ++ setOperationAction(ISD::SMULO, MVT::i64, Custom); + } + + // VASTART needs to be custom lowered to use the VarArgsFrameIndex. +@@ -2673,6 +2676,53 @@ static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op + return DAG.getMergeValues(Ops, 2, dl); + } + ++// Custom lower UMULO/SMULO for SPARC. This code is similar to ExpandNode() ++// in LegalizeDAG.cpp except the order of arguments to the library function. ++static SDValue LowerUMULO_SMULO(SDValue Op, SelectionDAG &DAG, ++ const SparcTargetLowering &TLI) ++{ ++ unsigned opcode = Op.getOpcode(); ++ assert((opcode == ISD::UMULO || opcode == ISD::SMULO) && "Invalid Opcode."); ++ ++ bool isSigned = (opcode == ISD::SMULO); ++ EVT VT = MVT::i64; ++ EVT WideVT = MVT::i128; ++ SDLoc dl(Op); ++ SDValue LHS = Op.getOperand(0); ++ ++ if (LHS.getValueType() != VT) ++ return Op; ++ ++ SDValue ShiftAmt = DAG.getConstant(63, VT); ++ ++ SDValue RHS = Op.getOperand(1); ++ SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, LHS, ShiftAmt); ++ SDValue HiRHS = DAG.getNode(ISD::SRA, dl, MVT::i64, RHS, ShiftAmt); ++ SDValue Args[] = { HiLHS, LHS, HiRHS, RHS }; ++ ++ SDValue MulResult = TLI.makeLibCall(DAG, ++ RTLIB::MUL_I128, WideVT, ++ Args, 4, isSigned, dl).first; ++ SDValue BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, ++ MulResult, DAG.getIntPtrConstant(0)); ++ SDValue TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, ++ MulResult, DAG.getIntPtrConstant(1)); ++ if (isSigned) { ++ SDValue Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, ShiftAmt); ++ TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, Tmp1, ISD::SETNE); ++ } else { ++ TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, DAG.getConstant(0, VT), ++ ISD::SETNE); ++ } ++ // MulResult is a node with an illegal type. Because such things are not ++ // generally permitted during this phase of legalization, delete the ++ // node. The above EXTRACT_ELEMENT nodes should have been folded. ++ DAG.DeleteNode(MulResult.getNode()); ++ ++ SDValue Ops[2] = { BottomHalf, TopHalf } ; ++ return DAG.getMergeValues(Ops, 2, dl); ++} ++ + SDValue SparcTargetLowering:: + LowerOperation(SDValue Op, SelectionDAG &DAG) const { + +@@ -2726,6 +2776,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons + case ISD::ADDE: + case ISD::SUBC: + case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG); ++ case ISD::UMULO: ++ case ISD::SMULO: return LowerUMULO_SMULO(Op, DAG, *this); + } + } + +Index: test/CodeGen/SPARC/64cond.ll +=================================================================== +--- test/CodeGen/SPARC/64cond.ll ++++ test/CodeGen/SPARC/64cond.ll +@@ -111,6 +111,11 @@ entry: + } + + ; CHECK-LABEL: setcc_resultty ++; CHECK-DAG: srax %i0, 63, %o0 ++; CHECK-DAG: or %g0, %i0, %o1 ++; CHECK-DAG: or %g0, 0, %o2 ++; CHECK-DAG: or %g0, 32, %o3 ++; CHECK-DAG: call __multi3 + ; CHECK: cmp + ; CHECK: movne %xcc, 1, [[R:%[gilo][0-7]]] + ; CHECK: or [[R]], %i1, %i0 |