Skip to content

Commit d1bf26f

Browse files
committed
[AArch64][SVE] Add lowering for llvm abs intrinsic
Add functionality to permit lowering of the abs and neg intrinsics using the passthru variants. Differential Revision: https://reviews.llvm.org/D94160
1 parent 7a91dad commit d1bf26f

File tree

6 files changed

+420
-7
lines changed

6 files changed

+420
-7
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ static bool isMergePassthruOpcode(unsigned Opc) {
187187
case AArch64ISD::CTLZ_MERGE_PASSTHRU:
188188
case AArch64ISD::CTPOP_MERGE_PASSTHRU:
189189
case AArch64ISD::DUP_MERGE_PASSTHRU:
190+
case AArch64ISD::ABS_MERGE_PASSTHRU:
191+
case AArch64ISD::NEG_MERGE_PASSTHRU:
190192
case AArch64ISD::FNEG_MERGE_PASSTHRU:
191193
case AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU:
192194
case AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU:
@@ -1097,6 +1099,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
10971099
setOperationAction(ISD::SHL, VT, Custom);
10981100
setOperationAction(ISD::SRL, VT, Custom);
10991101
setOperationAction(ISD::SRA, VT, Custom);
1102+
setOperationAction(ISD::ABS, VT, Custom);
11001103
setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
11011104
setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
11021105
setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
@@ -1345,6 +1348,7 @@ void AArch64TargetLowering::addTypeForFixedLengthSVE(MVT VT) {
13451348
setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Custom);
13461349

13471350
// Lower fixed length vector operations to scalable equivalents.
1351+
setOperationAction(ISD::ABS, VT, Custom);
13481352
setOperationAction(ISD::ADD, VT, Custom);
13491353
setOperationAction(ISD::AND, VT, Custom);
13501354
setOperationAction(ISD::ANY_EXTEND, VT, Custom);
@@ -1743,6 +1747,8 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
17431747
MAKE_CASE(AArch64ISD::FSQRT_MERGE_PASSTHRU)
17441748
MAKE_CASE(AArch64ISD::FRECPX_MERGE_PASSTHRU)
17451749
MAKE_CASE(AArch64ISD::FABS_MERGE_PASSTHRU)
1750+
MAKE_CASE(AArch64ISD::ABS_MERGE_PASSTHRU)
1751+
MAKE_CASE(AArch64ISD::NEG_MERGE_PASSTHRU)
17461752
MAKE_CASE(AArch64ISD::SETCC_MERGE_ZERO)
17471753
MAKE_CASE(AArch64ISD::ADC)
17481754
MAKE_CASE(AArch64ISD::SBC)
@@ -3661,6 +3667,12 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
36613667
case Intrinsic::aarch64_sve_fabs:
36623668
return DAG.getNode(AArch64ISD::FABS_MERGE_PASSTHRU, dl, Op.getValueType(),
36633669
Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
3670+
case Intrinsic::aarch64_sve_abs:
3671+
return DAG.getNode(AArch64ISD::ABS_MERGE_PASSTHRU, dl, Op.getValueType(),
3672+
Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
3673+
case Intrinsic::aarch64_sve_neg:
3674+
return DAG.getNode(AArch64ISD::NEG_MERGE_PASSTHRU, dl, Op.getValueType(),
3675+
Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
36643676
case Intrinsic::aarch64_sve_convert_to_svbool: {
36653677
EVT OutVT = Op.getValueType();
36663678
EVT InVT = Op.getOperand(1).getValueType();
@@ -4163,9 +4175,12 @@ SDValue AArch64TargetLowering::LowerSTORE(SDValue Op,
41634175
}
41644176

41654177
// Generate SUBS and CSEL for integer abs.
4166-
static SDValue LowerABS(SDValue Op, SelectionDAG &DAG) {
4178+
SDValue AArch64TargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
41674179
MVT VT = Op.getSimpleValueType();
41684180

4181+
if (VT.isVector())
4182+
return LowerToPredicatedOp(Op, DAG, AArch64ISD::ABS_MERGE_PASSTHRU);
4183+
41694184
SDLoc DL(Op);
41704185
SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
41714186
Op.getOperand(0));

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ enum NodeType : unsigned {
114114
FCVTZS_MERGE_PASSTHRU,
115115
SIGN_EXTEND_INREG_MERGE_PASSTHRU,
116116
ZERO_EXTEND_INREG_MERGE_PASSTHRU,
117+
ABS_MERGE_PASSTHRU,
118+
NEG_MERGE_PASSTHRU,
117119

118120
SETCC_MERGE_ZERO,
119121

@@ -812,6 +814,7 @@ class AArch64TargetLowering : public TargetLowering {
812814
SDValue ThisVal) const;
813815

814816
SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
817+
SDValue LowerABS(SDValue Op, SelectionDAG &DAG) const;
815818

816819
SDValue LowerMGATHER(SDValue Op, SelectionDAG &DAG) const;
817820
SDValue LowerMSCATTER(SDValue Op, SelectionDAG &DAG) const;

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ def AArch64clz_mt : SDNode<"AArch64ISD::CTLZ_MERGE_PASSTHRU", SDT_AArch64Arit
205205
def AArch64cnt_mt : SDNode<"AArch64ISD::CTPOP_MERGE_PASSTHRU", SDT_AArch64Arith>;
206206
def AArch64fneg_mt : SDNode<"AArch64ISD::FNEG_MERGE_PASSTHRU", SDT_AArch64Arith>;
207207
def AArch64fabs_mt : SDNode<"AArch64ISD::FABS_MERGE_PASSTHRU", SDT_AArch64Arith>;
208+
def AArch64abs_mt : SDNode<"AArch64ISD::ABS_MERGE_PASSTHRU", SDT_AArch64Arith>;
209+
def AArch64neg_mt : SDNode<"AArch64ISD::NEG_MERGE_PASSTHRU", SDT_AArch64Arith>;
208210
def AArch64sxt_mt : SDNode<"AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU", SDT_AArch64IntExtend>;
209211
def AArch64uxt_mt : SDNode<"AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU", SDT_AArch64IntExtend>;
210212
def AArch64frintp_mt : SDNode<"AArch64ISD::FCEIL_MERGE_PASSTHRU", SDT_AArch64Arith>;
@@ -376,8 +378,8 @@ let Predicates = [HasSVE] in {
376378
defm UXTH_ZPmZ : sve_int_un_pred_arit_0_w<0b011, "uxth", AArch64uxt_mt>;
377379
defm SXTW_ZPmZ : sve_int_un_pred_arit_0_d<0b100, "sxtw", AArch64sxt_mt>;
378380
defm UXTW_ZPmZ : sve_int_un_pred_arit_0_d<0b101, "uxtw", AArch64uxt_mt>;
379-
defm ABS_ZPmZ : sve_int_un_pred_arit_0< 0b110, "abs", int_aarch64_sve_abs>;
380-
defm NEG_ZPmZ : sve_int_un_pred_arit_0< 0b111, "neg", int_aarch64_sve_neg>;
381+
defm ABS_ZPmZ : sve_int_un_pred_arit_0< 0b110, "abs", AArch64abs_mt>;
382+
defm NEG_ZPmZ : sve_int_un_pred_arit_0< 0b111, "neg", AArch64neg_mt>;
381383

382384
defm CLS_ZPmZ : sve_int_un_pred_arit_1< 0b000, "cls", AArch64cls_mt>;
383385
defm CLZ_ZPmZ : sve_int_un_pred_arit_1< 0b001, "clz", AArch64clz_mt>;

llvm/lib/Target/AArch64/SVEInstrFormats.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3777,10 +3777,10 @@ multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
37773777
def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>;
37783778
def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>;
37793779

3780-
def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
3781-
def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
3782-
def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
3783-
def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
3780+
def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
3781+
def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
3782+
def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
3783+
def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
37843784
}
37853785

37863786
multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,

0 commit comments

Comments
 (0)