Skip to content

Commit 5abf80c

Browse files
author
Krzysztof Parzyszek
committed
[Hexagon] Custom-lower UADDO(x, 1) and USUBO(x, 1)
llvm-svn: 364790
1 parent cda82f0 commit 5abf80c

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

llvm/lib/Target/Hexagon/HexagonISelLowering.cpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
26942731
SDValue
26952732
HexagonTargetLowering::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:

llvm/lib/Target/Hexagon/HexagonISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ namespace HexagonISD {
167167
SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const;
168168
SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const;
169169
SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;
170+
SDValue LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const;
170171
SDValue LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const;
171172

172173
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; RUN: llc -march=hexagon < %s | FileCheck %s
2+
3+
; Check that a hardware loop is generated.
4+
; CHECK: loop0
5+
6+
target triple = "hexagon"
7+
8+
; Function Attrs: norecurse nounwind
9+
define dso_local void @f0(i32* nocapture readonly %a0, i32* nocapture %a1) local_unnamed_addr #0 {
10+
b0:
11+
br label %b1
12+
13+
b1: ; preds = %b1, %b0
14+
%v0 = phi i32 [ %v3, %b1 ], [ 100, %b0 ]
15+
%v1 = phi i32* [ %v6, %b1 ], [ %a1, %b0 ]
16+
%v2 = phi i32* [ %v4, %b1 ], [ %a0, %b0 ]
17+
%v3 = add nsw i32 %v0, -1
18+
%v4 = getelementptr inbounds i32, i32* %v2, i32 1
19+
%v5 = load i32, i32* %v2, align 4, !tbaa !1
20+
%v6 = getelementptr inbounds i32, i32* %v1, i32 1
21+
store i32 %v5, i32* %v1, align 4, !tbaa !1
22+
%v7 = icmp eq i32 %v3, 0
23+
br i1 %v7, label %b2, label %b1
24+
25+
b2: ; preds = %b1
26+
ret void
27+
}
28+
29+
attributes #0 = { norecurse nounwind "target-cpu"="hexagonv62" }
30+
31+
!llvm.module.flags = !{!0}
32+
33+
!0 = !{i32 1, !"wchar_size", i32 4}
34+
!1 = !{!2, !2, i64 0}
35+
!2 = !{!"int", !3, i64 0}
36+
!3 = !{!"omnipotent char", !4, i64 0}
37+
!4 = !{!"Simple C/C++ TBAA"}

0 commit comments

Comments
 (0)