@@ -1334,8 +1334,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
13341334 // Hexagon has A4_addp_c and A4_subp_c that take and generate a carry bit,
13351335 // but they only operate on i64.
13361336 for (MVT VT : MVT::integer_valuetypes ()) {
1337- setOperationAction (ISD::UADDO, VT, Expand );
1338- setOperationAction (ISD::USUBO, VT, Expand );
1337+ setOperationAction (ISD::UADDO, VT, Custom );
1338+ setOperationAction (ISD::USUBO, VT, Custom );
13391339 setOperationAction (ISD::SADDO, VT, Expand);
13401340 setOperationAction (ISD::SSUBO, VT, Expand);
13411341 setOperationAction (ISD::ADDCARRY, VT, Expand);
@@ -2691,6 +2691,43 @@ HexagonTargetLowering::LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG)
26912691 return M;
26922692}
26932693
2694+ SDValue
2695+ HexagonTargetLowering::LowerUAddSubO (SDValue Op, SelectionDAG &DAG) const {
2696+ SDValue X = Op.getOperand (0 ), Y = Op.getOperand (1 );
2697+ auto *CY = dyn_cast<ConstantSDNode>(Y);
2698+ if (!CY)
2699+ return SDValue ();
2700+
2701+ const SDLoc &dl (Op);
2702+ SDVTList VTs = Op.getNode ()->getVTList ();
2703+ assert (VTs.NumVTs == 2 );
2704+ assert (VTs.VTs [1 ] == MVT::i1);
2705+ unsigned Opc = Op.getOpcode ();
2706+
2707+ if (CY) {
2708+ uint32_t VY = CY->getZExtValue ();
2709+ assert (VY != 0 && " This should have been folded" );
2710+ // X +/- 1
2711+ if (VY != 1 )
2712+ return SDValue ();
2713+
2714+ if (Opc == ISD::UADDO) {
2715+ SDValue Op = DAG.getNode (ISD::ADD, dl, VTs.VTs [0 ], {X, Y});
2716+ SDValue Ov = DAG.getSetCC (dl, MVT::i1, Op, getZero (dl, ty (Op), DAG),
2717+ ISD::SETEQ);
2718+ return DAG.getMergeValues ({Op, Ov}, dl);
2719+ }
2720+ if (Opc == ISD::USUBO) {
2721+ SDValue Op = DAG.getNode (ISD::SUB, dl, VTs.VTs [0 ], {X, Y});
2722+ SDValue Ov = DAG.getSetCC (dl, MVT::i1, Op,
2723+ DAG.getConstant (-1 , dl, ty (Op)), ISD::SETEQ);
2724+ return DAG.getMergeValues ({Op, Ov}, dl);
2725+ }
2726+ }
2727+
2728+ return SDValue ();
2729+ }
2730+
26942731SDValue
26952732HexagonTargetLowering::LowerAddSubCarry (SDValue Op, SelectionDAG &DAG) const {
26962733 const SDLoc &dl (Op);
@@ -2768,6 +2805,8 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
27682805 case ISD::BITCAST: return LowerBITCAST (Op, DAG);
27692806 case ISD::LOAD: return LowerLoad (Op, DAG);
27702807 case ISD::STORE: return LowerStore (Op, DAG);
2808+ case ISD::UADDO:
2809+ case ISD::USUBO: return LowerUAddSubO (Op, DAG);
27712810 case ISD::ADDCARRY:
27722811 case ISD::SUBCARRY: return LowerAddSubCarry (Op, DAG);
27732812 case ISD::SRA:
0 commit comments