From 3e56c9d4260b091ecb0332e96615f1186605ac99 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 1 Jul 2019 15:50:09 +0000 Subject: [PATCH] [Hexagon] Custom-lower UADDO(x, 1) and USUBO(x, 1) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364790 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonISelLowering.cpp | 43 +++++++++++++++++++++- lib/Target/Hexagon/HexagonISelLowering.h | 1 + test/CodeGen/Hexagon/isel-uaddo-1.ll | 37 +++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/Hexagon/isel-uaddo-1.ll diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp index b72498777ed..fef5a98cdb0 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -1334,8 +1334,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, // Hexagon has A4_addp_c and A4_subp_c that take and generate a carry bit, // but they only operate on i64. for (MVT VT : MVT::integer_valuetypes()) { - setOperationAction(ISD::UADDO, VT, Expand); - setOperationAction(ISD::USUBO, VT, Expand); + setOperationAction(ISD::UADDO, VT, Custom); + setOperationAction(ISD::USUBO, VT, Custom); setOperationAction(ISD::SADDO, VT, Expand); setOperationAction(ISD::SSUBO, VT, Expand); setOperationAction(ISD::ADDCARRY, VT, Expand); @@ -2691,6 +2691,43 @@ HexagonTargetLowering::LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) return M; } +SDValue +HexagonTargetLowering::LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const { + SDValue X = Op.getOperand(0), Y = Op.getOperand(1); + auto *CY = dyn_cast(Y); + if (!CY) + return SDValue(); + + const SDLoc &dl(Op); + SDVTList VTs = Op.getNode()->getVTList(); + assert(VTs.NumVTs == 2); + assert(VTs.VTs[1] == MVT::i1); + unsigned Opc = Op.getOpcode(); + + if (CY) { + uint32_t VY = CY->getZExtValue(); + assert(VY != 0 && "This should have been folded"); + // X +/- 1 + if (VY != 1) + return SDValue(); + + if (Opc == ISD::UADDO) { + SDValue Op = DAG.getNode(ISD::ADD, dl, VTs.VTs[0], {X, Y}); + SDValue Ov = DAG.getSetCC(dl, MVT::i1, Op, getZero(dl, ty(Op), DAG), + ISD::SETEQ); + return DAG.getMergeValues({Op, Ov}, dl); + } + if (Opc == ISD::USUBO) { + SDValue Op = DAG.getNode(ISD::SUB, dl, VTs.VTs[0], {X, Y}); + SDValue Ov = DAG.getSetCC(dl, MVT::i1, Op, + DAG.getConstant(-1, dl, ty(Op)), ISD::SETEQ); + return DAG.getMergeValues({Op, Ov}, dl); + } + } + + return SDValue(); +} + SDValue HexagonTargetLowering::LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const { const SDLoc &dl(Op); @@ -2768,6 +2805,8 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::BITCAST: return LowerBITCAST(Op, DAG); case ISD::LOAD: return LowerLoad(Op, DAG); case ISD::STORE: return LowerStore(Op, DAG); + case ISD::UADDO: + case ISD::USUBO: return LowerUAddSubO(Op, DAG); case ISD::ADDCARRY: case ISD::SUBCARRY: return LowerAddSubCarry(Op, DAG); case ISD::SRA: diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h index 7c86bbf62a3..4e467cb2272 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.h +++ b/lib/Target/Hexagon/HexagonISelLowering.h @@ -167,6 +167,7 @@ namespace HexagonISD { SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const; SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const; SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const; SDValue LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const; SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; diff --git a/test/CodeGen/Hexagon/isel-uaddo-1.ll b/test/CodeGen/Hexagon/isel-uaddo-1.ll new file mode 100644 index 00000000000..092fb60e041 --- /dev/null +++ b/test/CodeGen/Hexagon/isel-uaddo-1.ll @@ -0,0 +1,37 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; Check that a hardware loop is generated. +; CHECK: loop0 + +target triple = "hexagon" + +; Function Attrs: norecurse nounwind +define dso_local void @f0(i32* nocapture readonly %a0, i32* nocapture %a1) local_unnamed_addr #0 { +b0: + br label %b1 + +b1: ; preds = %b1, %b0 + %v0 = phi i32 [ %v3, %b1 ], [ 100, %b0 ] + %v1 = phi i32* [ %v6, %b1 ], [ %a1, %b0 ] + %v2 = phi i32* [ %v4, %b1 ], [ %a0, %b0 ] + %v3 = add nsw i32 %v0, -1 + %v4 = getelementptr inbounds i32, i32* %v2, i32 1 + %v5 = load i32, i32* %v2, align 4, !tbaa !1 + %v6 = getelementptr inbounds i32, i32* %v1, i32 1 + store i32 %v5, i32* %v1, align 4, !tbaa !1 + %v7 = icmp eq i32 %v3, 0 + br i1 %v7, label %b2, label %b1 + +b2: ; preds = %b1 + ret void +} + +attributes #0 = { norecurse nounwind "target-cpu"="hexagonv62" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!2, !2, i64 0} +!2 = !{!"int", !3, i64 0} +!3 = !{!"omnipotent char", !4, i64 0} +!4 = !{!"Simple C/C++ TBAA"} -- 2.40.0