Skip to content

Commit 4334892

Browse files
committed
[DAGCombine][ARM] x ==/!= c -> (x - c) ==/!= 0 iff '-c' can be folded into the x node.
Summary: This fold, helps recover from the rest of the D62266 ARM regressions. https://rise4fun.com/Alive/TvpC Note that while the fold is quite flexible, i've restricted it to the single interesting pattern at the moment. Reviewers: efriedma, craig.topper, spatel, RKSimon, deadalnix Reviewed By: deadalnix Subscribers: javed.absar, kristof.beyls, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62450
1 parent 9b1419a commit 4334892

File tree

3 files changed

+86
-44
lines changed

3 files changed

+86
-44
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

+7
Original file line numberDiff line numberDiff line change
@@ -4268,6 +4268,13 @@ class TargetLowering : public TargetLoweringBase {
42684268
SDValue buildSREMEqFold(EVT SETCCVT, SDValue REMNode, SDValue CompTargetNode,
42694269
ISD::CondCode Cond, DAGCombinerInfo &DCI,
42704270
const SDLoc &DL) const;
4271+
4272+
/// x ==/!= c -> (x - c) ==/!= 0 iff '-c' can be folded into the x node.
4273+
SDValue optimizeSetCCToComparisonWithZero(EVT SCCVT, SDValue N0,
4274+
ConstantSDNode *N1C,
4275+
ISD::CondCode Cond,
4276+
DAGCombinerInfo &DCI,
4277+
const SDLoc &DL) const;
42714278
};
42724279

42734280
/// Given an LLVM IR type and return type attributes, compute the return value

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -3045,6 +3045,62 @@ SDValue TargetLowering::foldSetCCWithBinOp(EVT VT, SDValue N0, SDValue N1,
30453045
return DAG.getSetCC(DL, VT, X, YShl1, Cond);
30463046
}
30473047

3048+
/// x ==/!= c -> (x - c) ==/!= 0 iff '-c' can be folded into the x node.
3049+
SDValue TargetLowering::optimizeSetCCToComparisonWithZero(
3050+
EVT SCCVT, SDValue N0, ConstantSDNode *N1C, ISD::CondCode Cond,
3051+
DAGCombinerInfo &DCI, const SDLoc &DL) const {
3052+
assert((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
3053+
"Only for equality-comparisons.");
3054+
3055+
// LHS should not be used elsewhere, to avoid creating an extra node.
3056+
if (!N0.hasOneUse())
3057+
return SDValue();
3058+
3059+
// Will we able to fold the '-c' into 'x' node?
3060+
bool IsAdd;
3061+
switch (N0.getOpcode()) {
3062+
default:
3063+
return SDValue(); // Don't know about that node.
3064+
case ISD::ADD:
3065+
case ISD::SUB:
3066+
return SDValue(); // Let's not touch these.
3067+
case ISD::ADDCARRY:
3068+
IsAdd = true;
3069+
break;
3070+
case ISD::SUBCARRY:
3071+
IsAdd = false;
3072+
break;
3073+
}
3074+
3075+
// Second operand must be a constant.
3076+
ConstantSDNode *N01C = isConstOrConstSplat(N0.getOperand(1));
3077+
if (!N01C)
3078+
return SDValue();
3079+
3080+
// And let's be even more specific for now, it must be a zero constant.
3081+
// It is possible to relax this requirement, but a precise cost-model needed.
3082+
if (!N01C->isNullValue())
3083+
return SDValue();
3084+
3085+
SelectionDAG &DAG = DCI.DAG;
3086+
EVT OpVT = N0.getValueType();
3087+
3088+
// (y + N01C) - N1C = y + (N01C - N1C)
3089+
// (y - N01C) - N1C = y - (N01C + N1C)
3090+
SDValue NewC = DAG.FoldConstantArithmetic(IsAdd ? ISD::SUB : ISD::ADD, DL,
3091+
OpVT, N01C, N1C);
3092+
assert(NewC && "Constant-folding failed!");
3093+
3094+
SmallVector<SDValue, 3> N0Ops(N0.getNode()->ops().begin(),
3095+
N0.getNode()->ops().end());
3096+
N0Ops[1] = NewC;
3097+
3098+
N0 = DAG.getNode(N0.getOpcode(), DL, N0->getVTList(), N0Ops);
3099+
3100+
SDValue Zero = DAG.getConstant(0, DL, OpVT);
3101+
return DAG.getSetCC(DL, SCCVT, N0, Zero, Cond);
3102+
}
3103+
30483104
/// Try to simplify a setcc built with the specified operands and cc. If it is
30493105
/// unable to simplify it, return a null SDValue.
30503106
SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
@@ -3578,6 +3634,11 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
35783634
return CC;
35793635
}
35803636

3637+
if (Cond == ISD::SETEQ || Cond == ISD::SETNE)
3638+
if (SDValue CC =
3639+
optimizeSetCCToComparisonWithZero(VT, N0, N1C, Cond, DCI, dl))
3640+
return CC;
3641+
35813642
// If we have "setcc X, C0", check to see if we can shrink the immediate
35823643
// by changing cc.
35833644
// TODO: Support this for vectors after legalize ops.

llvm/test/CodeGen/ARM/addsubcarry-promotion.ll

+18-44
Original file line numberDiff line numberDiff line change
@@ -14,61 +14,35 @@ define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 {
1414
; ARM-NEXT: adds r0, r1, r0
1515
; ARM-NEXT: movw r1, #65535
1616
; ARM-NEXT: sxth r2, r2
17-
; ARM-NEXT: adc r0, r2, #0
18-
; ARM-NEXT: uxth r0, r0
19-
; ARM-NEXT: cmp r0, r1
17+
; ARM-NEXT: adc r0, r2, #1
18+
; ARM-NEXT: tst r0, r1
2019
; ARM-NEXT: bxeq lr
2120
; ARM-NEXT: .LBB0_1: @ %for.cond
2221
; ARM-NEXT: @ =>This Inner Loop Header: Depth=1
2322
; ARM-NEXT: b .LBB0_1
2423
;
25-
; THUMBV6M-LABEL: fn1:
26-
; THUMBV6M: @ %bb.0: @ %entry
27-
; THUMBV6M-NEXT: rsbs r2, r2, #0
28-
; THUMBV6M-NEXT: sxth r2, r2
29-
; THUMBV6M-NEXT: movs r3, #0
30-
; THUMBV6M-NEXT: adds r0, r1, r0
31-
; THUMBV6M-NEXT: adcs r3, r2
32-
; THUMBV6M-NEXT: uxth r0, r3
33-
; THUMBV6M-NEXT: ldr r1, .LCPI0_0
34-
; THUMBV6M-NEXT: cmp r0, r1
35-
; THUMBV6M-NEXT: beq .LBB0_2
36-
; THUMBV6M-NEXT: .LBB0_1: @ %for.cond
37-
; THUMBV6M-NEXT: @ =>This Inner Loop Header: Depth=1
38-
; THUMBV6M-NEXT: b .LBB0_1
39-
; THUMBV6M-NEXT: .LBB0_2: @ %if.end
40-
; THUMBV6M-NEXT: bx lr
41-
; THUMBV6M-NEXT: .p2align 2
42-
; THUMBV6M-NEXT: @ %bb.3:
43-
; THUMBV6M-NEXT: .LCPI0_0:
44-
; THUMBV6M-NEXT: .long 65535 @ 0xffff
45-
;
46-
; THUMBV8M-BASE-LABEL: fn1:
47-
; THUMBV8M-BASE: @ %bb.0: @ %entry
48-
; THUMBV8M-BASE-NEXT: rsbs r2, r2, #0
49-
; THUMBV8M-BASE-NEXT: sxth r2, r2
50-
; THUMBV8M-BASE-NEXT: movs r3, #0
51-
; THUMBV8M-BASE-NEXT: adds r0, r1, r0
52-
; THUMBV8M-BASE-NEXT: adcs r3, r2
53-
; THUMBV8M-BASE-NEXT: uxth r0, r3
54-
; THUMBV8M-BASE-NEXT: movw r1, #65535
55-
; THUMBV8M-BASE-NEXT: cmp r0, r1
56-
; THUMBV8M-BASE-NEXT: beq .LBB0_2
57-
; THUMBV8M-BASE-NEXT: .LBB0_1: @ %for.cond
58-
; THUMBV8M-BASE-NEXT: @ =>This Inner Loop Header: Depth=1
59-
; THUMBV8M-BASE-NEXT: b .LBB0_1
60-
; THUMBV8M-BASE-NEXT: .LBB0_2: @ %if.end
61-
; THUMBV8M-BASE-NEXT: bx lr
24+
; THUMB1-LABEL: fn1:
25+
; THUMB1: @ %bb.0: @ %entry
26+
; THUMB1-NEXT: rsbs r2, r2, #0
27+
; THUMB1-NEXT: sxth r2, r2
28+
; THUMB1-NEXT: movs r3, #1
29+
; THUMB1-NEXT: adds r0, r1, r0
30+
; THUMB1-NEXT: adcs r3, r2
31+
; THUMB1-NEXT: lsls r0, r3, #16
32+
; THUMB1-NEXT: beq .LBB0_2
33+
; THUMB1-NEXT: .LBB0_1: @ %for.cond
34+
; THUMB1-NEXT: @ =>This Inner Loop Header: Depth=1
35+
; THUMB1-NEXT: b .LBB0_1
36+
; THUMB1-NEXT: .LBB0_2: @ %if.end
37+
; THUMB1-NEXT: bx lr
6238
;
6339
; THUMB-LABEL: fn1:
6440
; THUMB: @ %bb.0: @ %entry
6541
; THUMB-NEXT: rsbs r2, r2, #0
6642
; THUMB-NEXT: adds r0, r0, r1
67-
; THUMB-NEXT: movw r1, #65535
6843
; THUMB-NEXT: sxth r2, r2
69-
; THUMB-NEXT: adc r0, r2, #0
70-
; THUMB-NEXT: uxth r0, r0
71-
; THUMB-NEXT: cmp r0, r1
44+
; THUMB-NEXT: adc r0, r2, #1
45+
; THUMB-NEXT: lsls r0, r0, #16
7246
; THUMB-NEXT: it eq
7347
; THUMB-NEXT: bxeq lr
7448
; THUMB-NEXT: .LBB0_1: @ %for.cond

0 commit comments

Comments
 (0)