Skip to content

Commit ada9ab6

Browse files
committed
[AArch64] Adjust operand sequence for Add+Sub to combine more inline shift
((X >> C) - Y) + Z --> (Z - Y) + (X >> C) Fix AArch part: #55714 Reviewed By: dmgreen Differential Revision: https://reviews.llvm.org/D136158
1 parent 2e1e2f5 commit ada9ab6

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16854,6 +16854,32 @@ static SDValue performBuildVectorCombine(SDNode *N,
1685416854
return SDValue();
1685516855
}
1685616856

16857+
// ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)
16858+
static SDValue performAddCombineSubShift(SDNode *N, SDValue SUB, SDValue Z,
16859+
SelectionDAG &DAG) {
16860+
// DAGCombiner will revert the combination when Z is constant cause
16861+
// dead loop. So don't enable the combination when Z is constant.
16862+
if (isa<ConstantSDNode>(Z))
16863+
return SDValue();
16864+
16865+
if (SUB.getOpcode() != ISD::SUB || !SUB.hasOneUse())
16866+
return SDValue();
16867+
16868+
SDValue SHL = SUB.getOperand(0);
16869+
if (SHL.getOpcode() != ISD::SHL || !SHL.hasOneUse())
16870+
return SDValue();
16871+
16872+
if (!isa<ConstantSDNode>(SHL.getOperand(1)))
16873+
return SDValue();
16874+
16875+
SDLoc DL(N);
16876+
EVT VT = N->getValueType(0);
16877+
16878+
SDValue Y = SUB.getOperand(1);
16879+
SDValue NewSub = DAG.getNode(ISD::SUB, DL, VT, Z, Y);
16880+
return DAG.getNode(ISD::ADD, DL, VT, NewSub, SHL);
16881+
}
16882+
1685716883
static SDValue performAddCombineForShiftedOperands(SDNode *N,
1685816884
SelectionDAG &DAG) {
1685916885
// NOTE: Swapping LHS and RHS is not done for SUB, since SUB is not
@@ -16871,6 +16897,11 @@ static SDValue performAddCombineForShiftedOperands(SDNode *N,
1687116897
SDValue LHS = N->getOperand(0);
1687216898
SDValue RHS = N->getOperand(1);
1687316899

16900+
if (SDValue Val = performAddCombineSubShift(N, LHS, RHS, DAG))
16901+
return Val;
16902+
if (SDValue Val = performAddCombineSubShift(N, RHS, LHS, DAG))
16903+
return Val;
16904+
1687416905
uint64_t LHSImm = 0, RHSImm = 0;
1687516906
// If both operand are shifted by imm and shift amount is not greater than 4
1687616907
// for one operand, swap LHS and RHS to put operand with smaller shift amount

llvm/test/CodeGen/AArch64/addsub.ll

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -694,40 +694,55 @@ if.end: ; preds = %if.then, %lor.lhs.f
694694
ret i32 undef
695695
}
696696

697+
; ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)
697698
define i32 @commute_subop0(i32 %x, i32 %y, i32 %z) {
698699
; CHECK-LABEL: commute_subop0:
699700
; CHECK: // %bb.0:
700-
; CHECK-NEXT: lsl w8, w0, #3
701-
; CHECK-NEXT: sub w8, w8, w1
702-
; CHECK-NEXT: add w0, w8, w2
701+
; CHECK-NEXT: sub w8, w2, w1
702+
; CHECK-NEXT: add w0, w8, w0, lsl #3
703703
; CHECK-NEXT: ret
704704
%shl = shl i32 %x, 3
705705
%sub = sub i32 %shl, %y
706706
%add = add i32 %sub, %z
707707
ret i32 %add
708708
}
709709

710+
; Z + ((X >> C) - Y) --> (Z - Y) + (X >> C)
710711
define i32 @commute_subop0_cadd(i32 %x, i32 %y, i32 %z) {
711712
; CHECK-LABEL: commute_subop0_cadd:
712713
; CHECK: // %bb.0:
713-
; CHECK-NEXT: lsl w8, w0, #3
714-
; CHECK-NEXT: sub w8, w8, w1
715-
; CHECK-NEXT: add w0, w2, w8
714+
; CHECK-NEXT: sub w8, w2, w1
715+
; CHECK-NEXT: add w0, w8, w0, lsl #3
716716
; CHECK-NEXT: ret
717717
%shl = shl i32 %x, 3
718718
%sub = sub i32 %shl, %y
719719
%add = add i32 %z, %sub
720720
ret i32 %add
721721
}
722722

723+
; Y + ((X >> C) - X) --> (Y - X) + (X >> C)
723724
define i32 @commute_subop0_mul(i32 %x, i32 %y) {
724725
; CHECK-LABEL: commute_subop0_mul:
725726
; CHECK: // %bb.0:
726-
; CHECK-NEXT: lsl w8, w0, #3
727-
; CHECK-NEXT: sub w8, w8, w0
728-
; CHECK-NEXT: add w0, w8, w1
727+
; CHECK-NEXT: sub w8, w1, w0
728+
; CHECK-NEXT: add w0, w8, w0, lsl #3
729729
; CHECK-NEXT: ret
730730
%mul = mul i32 %x, 7
731731
%add = add i32 %mul, %y
732732
ret i32 %add
733733
}
734+
735+
; negative case for ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)
736+
; Z can't be constant to avoid dead loop
737+
define i32 @commute_subop0_zconst(i32 %x, i32 %y) {
738+
; CHECK-LABEL: commute_subop0_zconst:
739+
; CHECK: // %bb.0:
740+
; CHECK-NEXT: lsl w8, w0, #3
741+
; CHECK-NEXT: sub w8, w8, w1
742+
; CHECK-NEXT: add w0, w8, #1
743+
; CHECK-NEXT: ret
744+
%shl = shl i32 %x, 3
745+
%sub = sub i32 %shl, %y
746+
%add = add i32 %sub, 1
747+
ret i32 %add
748+
}

0 commit comments

Comments
 (0)