Skip to content

Commit c55d9af

Browse files
committed
[AArch64] Add custom lowering for ISD::ABS
Instead of trying to pattern match the code produced by ISD::ABS expansion, just custom legalize ISD::ABS to the desired sequence. The one test change is because a DAG combine for (neg (abs)) is no longer firing because ISD::ABS is now Custom instead of Expand. Differential Revision: https://reviews.llvm.org/D92154
1 parent ad923ed commit c55d9af

File tree

2 files changed

+25
-35
lines changed

2 files changed

+25
-35
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
475475
setOperationAction(ISD::CTPOP, MVT::i64, Custom);
476476
setOperationAction(ISD::CTPOP, MVT::i128, Custom);
477477

478+
setOperationAction(ISD::ABS, MVT::i32, Custom);
479+
setOperationAction(ISD::ABS, MVT::i64, Custom);
480+
478481
setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
479482
setOperationAction(ISD::SDIVREM, MVT::i64, Expand);
480483
for (MVT VT : MVT::fixedlen_vector_valuetypes()) {
@@ -3968,6 +3971,22 @@ SDValue AArch64TargetLowering::LowerSTORE(SDValue Op,
39683971
return SDValue();
39693972
}
39703973

3974+
// Generate SUBS and CSEL for integer abs.
3975+
static SDValue LowerABS(SDValue Op, SelectionDAG &DAG) {
3976+
MVT VT = Op.getSimpleValueType();
3977+
3978+
SDLoc DL(Op);
3979+
SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
3980+
Op.getOperand(0));
3981+
// Generate SUBS & CSEL.
3982+
SDValue Cmp =
3983+
DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, MVT::i32),
3984+
Op.getOperand(0), DAG.getConstant(0, DL, VT));
3985+
return DAG.getNode(AArch64ISD::CSEL, DL, VT, Op.getOperand(0), Neg,
3986+
DAG.getConstant(AArch64CC::PL, DL, MVT::i32),
3987+
Cmp.getValue(1));
3988+
}
3989+
39713990
SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
39723991
SelectionDAG &DAG) const {
39733992
LLVM_DEBUG(dbgs() << "Custom lowering: ");
@@ -4197,6 +4216,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
41974216
return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMINNM_PRED);
41984217
case ISD::VSELECT:
41994218
return LowerFixedLengthVectorSelectToSVE(Op, DAG);
4219+
case ISD::ABS:
4220+
return LowerABS(Op, DAG);
42004221
}
42014222
}
42024223

@@ -11323,34 +11344,6 @@ static SDValue foldVectorXorShiftIntoCmp(SDNode *N, SelectionDAG &DAG,
1132311344
return DAG.getNode(AArch64ISD::CMGEz, SDLoc(N), VT, Shift.getOperand(0));
1132411345
}
1132511346

11326-
// Generate SUBS and CSEL for integer abs.
11327-
static SDValue performIntegerAbsCombine(SDNode *N, SelectionDAG &DAG) {
11328-
EVT VT = N->getValueType(0);
11329-
11330-
SDValue N0 = N->getOperand(0);
11331-
SDValue N1 = N->getOperand(1);
11332-
SDLoc DL(N);
11333-
11334-
// Check pattern of XOR(ADD(X,Y), Y) where Y is SRA(X, size(X)-1)
11335-
// and change it to SUB and CSEL.
11336-
if (VT.isInteger() && N->getOpcode() == ISD::XOR &&
11337-
N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 &&
11338-
N1.getOpcode() == ISD::SRA && N1.getOperand(0) == N0.getOperand(0))
11339-
if (ConstantSDNode *Y1C = dyn_cast<ConstantSDNode>(N1.getOperand(1)))
11340-
if (Y1C->getAPIntValue() == VT.getSizeInBits() - 1) {
11341-
SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
11342-
N0.getOperand(0));
11343-
// Generate SUBS & CSEL.
11344-
SDValue Cmp =
11345-
DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, MVT::i32),
11346-
N0.getOperand(0), DAG.getConstant(0, DL, VT));
11347-
return DAG.getNode(AArch64ISD::CSEL, DL, VT, N0.getOperand(0), Neg,
11348-
DAG.getConstant(AArch64CC::PL, DL, MVT::i32),
11349-
SDValue(Cmp.getNode(), 1));
11350-
}
11351-
return SDValue();
11352-
}
11353-
1135411347
// VECREDUCE_ADD( EXTEND(v16i8_type) ) to
1135511348
// VECREDUCE_ADD( DOTv16i8(v16i8_type) )
1135611349
static SDValue performVecReduceAddCombine(SDNode *N, SelectionDAG &DAG,
@@ -11430,10 +11423,7 @@ static SDValue performXorCombine(SDNode *N, SelectionDAG &DAG,
1143011423
if (DCI.isBeforeLegalizeOps())
1143111424
return SDValue();
1143211425

11433-
if (SDValue Cmp = foldVectorXorShiftIntoCmp(N, DAG, Subtarget))
11434-
return Cmp;
11435-
11436-
return performIntegerAbsCombine(N, DAG);
11426+
return foldVectorXorShiftIntoCmp(N, DAG, Subtarget);
1143711427
}
1143811428

1143911429
SDValue

llvm/test/CodeGen/AArch64/neg-abs.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ declare i64 @llvm.abs.i64(i64, i1 immarg)
77
define i64@neg_abs(i64 %x) {
88
; CHECK-LABEL: neg_abs:
99
; CHECK: // %bb.0:
10-
; CHECK-NEXT: asr x8, x0, #63
11-
; CHECK-NEXT: eor x9, x0, x8
12-
; CHECK-NEXT: sub x0, x8, x9
10+
; CHECK-NEXT: cmp x0, #0 // =0
11+
; CHECK-NEXT: cneg x8, x0, mi
12+
; CHECK-NEXT: neg x0, x8
1313
; CHECK-NEXT: ret
1414
%abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
1515
%neg = sub nsw i64 0, %abs

0 commit comments

Comments
 (0)