diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrFormats.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/SVEInstrFormats.td | 34 |
5 files changed, 67 insertions, 10 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 5362c0e0647..a51aa85a931 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -271,6 +271,10 @@ private: bool SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift); bool SelectSVELogicalImm(SDValue N, MVT VT, SDValue &Imm); + + bool SelectSVESignedArithImm(SDValue N, SDValue &Imm); + + bool SelectSVEArithImm(SDValue N, SDValue &Imm); }; } // end anonymous namespace @@ -2909,6 +2913,31 @@ bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SD return false; } +bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDValue N, SDValue &Imm) { + if (auto CNode = dyn_cast<ConstantSDNode>(N)) { + int64_t ImmVal = CNode->getSExtValue(); + SDLoc DL(N); + if (ImmVal >= -127 && ImmVal < 127) { + Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32); + return true; + } + } + return false; +} + +bool AArch64DAGToDAGISel::SelectSVEArithImm(SDValue N, SDValue &Imm) { + if (auto CNode = dyn_cast<ConstantSDNode>(N)) { + uint64_t ImmVal = CNode->getSExtValue(); + SDLoc DL(N); + ImmVal = ImmVal & 0xFF; + if (ImmVal < 256) { + Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32); + return true; + } + } + return false; +} + bool AArch64DAGToDAGISel::SelectSVELogicalImm(SDValue N, MVT VT, SDValue &Imm) { if (auto CNode = dyn_cast<ConstantSDNode>(N)) { uint64_t ImmVal = CNode->getZExtValue(); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index f4feceff092..97343fd5304 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -188,6 +188,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, setOperationAction(ISD::UADDSAT, VT, Legal); setOperationAction(ISD::SSUBSAT, VT, Legal); setOperationAction(ISD::USUBSAT, VT, Legal); + setOperationAction(ISD::SMAX, VT, Legal); + setOperationAction(ISD::UMAX, VT, Legal); + setOperationAction(ISD::SMIN, VT, Legal); + setOperationAction(ISD::UMIN, VT, Legal); } for (auto VT : diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index b22fc160d5d..c3efe03a098 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -305,7 +305,7 @@ def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { } def SImm8Operand : SImmOperand<8>; -def simm8 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 127; }]> { +def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 127; }]> { let ParserMatchClass = SImm8Operand; let DecoderMethod = "DecodeSImm<8>"; } diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 900ae5ab7f0..82af6dc0074 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -130,10 +130,10 @@ let Predicates = [HasSVE] in { defm EOR_ZI : sve_int_log_imm<0b01, "eor", "eon", xor>; defm AND_ZI : sve_int_log_imm<0b10, "and", "bic", and>; - defm SMAX_ZI : sve_int_arith_imm1<0b00, "smax", simm8>; - defm SMIN_ZI : sve_int_arith_imm1<0b10, "smin", simm8>; - defm UMAX_ZI : sve_int_arith_imm1<0b01, "umax", imm0_255>; - defm UMIN_ZI : sve_int_arith_imm1<0b11, "umin", imm0_255>; + defm SMAX_ZI : sve_int_arith_imm1<0b00, "smax", smax>; + defm SMIN_ZI : sve_int_arith_imm1<0b10, "smin", smin>; + defm UMAX_ZI : sve_int_arith_imm1_unsigned<0b01, "umax", umax>; + defm UMIN_ZI : sve_int_arith_imm1_unsigned<0b11, "umin", umin>; defm MUL_ZI : sve_int_arith_imm2<"mul">; defm MUL_ZPmZ : sve_int_bin_pred_arit_2<0b000, "mul", int_aarch64_sve_mul>; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 61562991499..385d1267be2 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -212,6 +212,8 @@ def SVELogicalImm16Pat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i16>", def SVELogicalImm32Pat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i32>", []>; def SVELogicalImm64Pat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64>", []>; +def SVEArithUImmPat : ComplexPattern<i32, 1, "SelectSVEArithImm", []>; +def SVEArithSImmPat : ComplexPattern<i32, 1, "SelectSVESignedArithImm", []>; class SVEExactFPImm<string Suffix, string ValA, string ValB> : AsmOperandClass { let Name = "SVEExactFPImmOperand" # Suffix; @@ -317,6 +319,11 @@ class SVE_1_Op_Imm_OptLsl_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty : Pat<(vt (op (vt zprty:$Op1), (vt (AArch64dup (it (cpx i32:$imm, i32:$shift)))))), (inst $Op1, i32:$imm, i32:$shift)>; +class SVE_1_Op_Imm_Arith_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty, + ValueType it, ComplexPattern cpx, Instruction inst> + : Pat<(vt (op (vt zprty:$Op1), (vt (AArch64dup (it (cpx i32:$imm)))))), + (inst $Op1, i32:$imm)>; + class SVE_1_Op_Imm_Log_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty, ValueType it, ComplexPattern cpx, Instruction inst> : Pat<(vt (op (vt zprty:$Op1), (vt (AArch64dup (it (cpx i64:$imm)))))), @@ -3506,11 +3513,28 @@ class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm, let ElementSize = ElementSizeNone; } -multiclass sve_int_arith_imm1<bits<2> opc, string asm, Operand immtype> { - def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, immtype>; - def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, immtype>; - def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, immtype>; - def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, immtype>; +multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> { + def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, simm8>; + def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, simm8>; + def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8>; + def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8>; + + def : SVE_1_Op_Imm_Arith_Pat<nxv16i8, op, ZPR8, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _B)>; + def : SVE_1_Op_Imm_Arith_Pat<nxv8i16, op, ZPR16, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _H)>; + def : SVE_1_Op_Imm_Arith_Pat<nxv4i32, op, ZPR32, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _S)>; + def : SVE_1_Op_Imm_Arith_Pat<nxv2i64, op, ZPR64, i64, SVEArithSImmPat, !cast<Instruction>(NAME # _D)>; +} + +multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> { + def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, imm0_255>; + def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, imm0_255>; + def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>; + def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>; + + def : SVE_1_Op_Imm_Arith_Pat<nxv16i8, op, ZPR8, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _B)>; + def : SVE_1_Op_Imm_Arith_Pat<nxv8i16, op, ZPR16, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _H)>; + def : SVE_1_Op_Imm_Arith_Pat<nxv4i32, op, ZPR32, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _S)>; + def : SVE_1_Op_Imm_Arith_Pat<nxv2i64, op, ZPR64, i64, SVEArithUImmPat, !cast<Instruction>(NAME # _D)>; } multiclass sve_int_arith_imm2<string asm> { |