Navigation Menu

Skip to content

Commit

Permalink
[AArch64][SVE] Add SVE index intrinsic
Browse files Browse the repository at this point in the history
Summary:
Implements the @llvm.aarch64.sve.index intrinsic, which
takes a scalar base and step value.

This patch also adds the printSImm function to AArch64InstPrinter
to ensure that immediates of type i8 & i16 are printed correctly.

Reviewers: sdesmalen, andwar, efriedma, dancgr, cameron.mcinally, rengolin

Reviewed By: cameron.mcinally

Subscribers: tatyana-krasnukha, tschuett, kristof.beyls, hiraditya, rkruppe, arphaman, psnobl, cfe-commits, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D74550
  • Loading branch information
kmclaughlin-arm committed Feb 17, 2020
1 parent e5043cd commit 633db60
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 14 deletions.
8 changes: 8 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsAArch64.td
Expand Up @@ -796,6 +796,12 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
LLVMPointerTo<0>],
[IntrArgMemOnly, NoCapture<2>]>;

class AdvSIMD_SVE_Index_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[LLVMVectorElementType<0>,
LLVMVectorElementType<0>],
[IntrNoMem]>;

class AdvSIMD_Merged1VectorArg_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
Expand Down Expand Up @@ -1237,6 +1243,8 @@ def int_aarch64_sve_stnt1 : AdvSIMD_1Vec_PredStore_Intrinsic;

def int_aarch64_sve_dup : AdvSIMD_SVE_DUP_Intrinsic;

def int_aarch64_sve_index : AdvSIMD_SVE_Index_Intrinsic;

//
// Integer arithmetic
//
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Expand Up @@ -1426,6 +1426,7 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
case AArch64ISD::STP: return "AArch64ISD::STP";
case AArch64ISD::STNP: return "AArch64ISD::STNP";
case AArch64ISD::DUP_PRED: return "AArch64ISD::DUP_PRED";
case AArch64ISD::INDEX_VECTOR: return "AArch64ISD::INDEX_VECTOR";
}
return nullptr;
}
Expand Down Expand Up @@ -10918,6 +10919,21 @@ static SDValue LowerSVEIntReduction(SDNode *N, unsigned Opc,
return SDValue();
}

static SDValue LowerSVEIntrinsicIndex(SDNode *N, SelectionDAG &DAG) {
SDLoc DL(N);
SDValue Op1 = N->getOperand(1);
SDValue Op2 = N->getOperand(2);
EVT ScalarTy = Op1.getValueType();

if ((ScalarTy == MVT::i8) || (ScalarTy == MVT::i16)) {
Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Op1);
Op2 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Op2);
}

return DAG.getNode(AArch64ISD::INDEX_VECTOR, DL, N->getValueType(0),
Op1, Op2);
}

static SDValue LowerSVEIntrinsicDUP(SDNode *N, SelectionDAG &DAG) {
SDLoc dl(N);
SDValue Scalar = N->getOperand(3);
Expand Down Expand Up @@ -11118,6 +11134,8 @@ static SDValue performIntrinsicCombine(SDNode *N,
return LowerSVEIntReduction(N, AArch64ISD::EORV_PRED, DAG);
case Intrinsic::aarch64_sve_andv:
return LowerSVEIntReduction(N, AArch64ISD::ANDV_PRED, DAG);
case Intrinsic::aarch64_sve_index:
return LowerSVEIntrinsicIndex(N, DAG);
case Intrinsic::aarch64_sve_dup:
return LowerSVEIntrinsicDUP(N, DAG);
case Intrinsic::aarch64_sve_ext:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.h
Expand Up @@ -216,6 +216,7 @@ enum NodeType : unsigned {
PTRUE,

DUP_PRED,
INDEX_VECTOR,

LDNF1,
LDNF1S,
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrFormats.td
Expand Up @@ -330,6 +330,18 @@ def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]>
let DecoderMethod = "DecodeSImm<5>";
}

def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> {
let ParserMatchClass = SImm5Operand;
let DecoderMethod = "DecodeSImm<5>";
let PrintMethod = "printSImm<8>";
}

def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> {
let ParserMatchClass = SImm5Operand;
let DecoderMethod = "DecodeSImm<5>";
let PrintMethod = "printSImm<16>";
}

// simm7sN predicate - True if the immediate is a multiple of N in the range
// [-64 * N, 63 * N].

Expand Down
11 changes: 7 additions & 4 deletions llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
Expand Up @@ -99,6 +99,9 @@ def AArch64ptest : SDNode<"AArch64ISD::PTEST", SDT_AArch64PTest>;
def SDT_AArch64DUP_PRED : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0,1>, SDTCisVec<2>, SDTCVecEltisVT<2,i1>]>;
def AArch64dup_pred : SDNode<"AArch64ISD::DUP_PRED", SDT_AArch64DUP_PRED>;

def SDT_IndexVector : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<1, 2>, SDTCisInt<2>]>;
def index_vector : SDNode<"AArch64ISD::INDEX_VECTOR", SDT_IndexVector, []>;

let Predicates = [HasSVE] in {

defm RDFFR_PPz : sve_int_rdffr_pred<0b0, "rdffr", int_aarch64_sve_rdffr_z>;
Expand Down Expand Up @@ -961,10 +964,10 @@ let Predicates = [HasSVE] in {
defm INCP_ZP : sve_int_count_v<0b10000, "incp">;
defm DECP_ZP : sve_int_count_v<0b10100, "decp">;

defm INDEX_RR : sve_int_index_rr<"index">;
defm INDEX_IR : sve_int_index_ir<"index">;
defm INDEX_RI : sve_int_index_ri<"index">;
defm INDEX_II : sve_int_index_ii<"index">;
defm INDEX_RR : sve_int_index_rr<"index", index_vector>;
defm INDEX_IR : sve_int_index_ir<"index", index_vector>;
defm INDEX_RI : sve_int_index_ri<"index", index_vector>;
defm INDEX_II : sve_int_index_ii<"index", index_vector>;

// Unpredicated shifts
defm ASR_ZZI : sve_int_bin_cons_shift_imm_right<0b00, "asr">;
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
Expand Up @@ -900,6 +900,19 @@ void AArch64InstPrinter::printImmHex(const MCInst *MI, unsigned OpNo,
O << format("#%#llx", Op.getImm());
}

template<int Size>
void AArch64InstPrinter::printSImm(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Size == 8)
O << "#" << formatImm((signed char)Op.getImm());
else if (Size == 16)
O << "#" << formatImm((signed short)Op.getImm());
else
O << "#" << formatImm(Op.getImm());
}

void AArch64InstPrinter::printPostIncOperand(const MCInst *MI, unsigned OpNo,
unsigned Imm, raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
Expand Up @@ -56,6 +56,9 @@ class AArch64InstPrinter : public MCInstPrinter {
raw_ostream &O);
void printImmHex(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
raw_ostream &O);
template <int Size>
void printSImm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
raw_ostream &O);
template <typename T> void printImmSVE(T Value, raw_ostream &O);
void printPostIncOperand(const MCInst *MI, unsigned OpNo, unsigned Imm,
raw_ostream &O);
Expand Down
52 changes: 42 additions & 10 deletions llvm/lib/Target/AArch64/SVEInstrFormats.td
Expand Up @@ -4386,11 +4386,20 @@ class sve_int_index_ii<bits<2> sz8_64, string asm, ZPRRegOp zprty,
let Inst{4-0} = Zd;
}

multiclass sve_int_index_ii<string asm> {
def _B : sve_int_index_ii<0b00, asm, ZPR8, simm5_32b>;
def _H : sve_int_index_ii<0b01, asm, ZPR16, simm5_32b>;
multiclass sve_int_index_ii<string asm, SDPatternOperator op> {
def _B : sve_int_index_ii<0b00, asm, ZPR8, simm5_8b>;
def _H : sve_int_index_ii<0b01, asm, ZPR16, simm5_16b>;
def _S : sve_int_index_ii<0b10, asm, ZPR32, simm5_32b>;
def _D : sve_int_index_ii<0b11, asm, ZPR64, simm5_64b>;

def : Pat<(nxv16i8 (op simm5_8b:$imm5, simm5_8b:$imm5b)),
(!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, simm5_8b:$imm5b)>;
def : Pat<(nxv8i16 (op simm5_16b:$imm5, simm5_16b:$imm5b)),
(!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, simm5_16b:$imm5b)>;
def : Pat<(nxv4i32 (op simm5_32b:$imm5, simm5_32b:$imm5b)),
(!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, simm5_32b:$imm5b)>;
def : Pat<(nxv2i64 (op simm5_64b:$imm5, simm5_64b:$imm5b)),
(!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, simm5_64b:$imm5b)>;
}

class sve_int_index_ir<bits<2> sz8_64, string asm, ZPRRegOp zprty,
Expand All @@ -4410,11 +4419,20 @@ class sve_int_index_ir<bits<2> sz8_64, string asm, ZPRRegOp zprty,
let Inst{4-0} = Zd;
}

multiclass sve_int_index_ir<string asm> {
def _B : sve_int_index_ir<0b00, asm, ZPR8, GPR32, simm5_32b>;
def _H : sve_int_index_ir<0b01, asm, ZPR16, GPR32, simm5_32b>;
multiclass sve_int_index_ir<string asm, SDPatternOperator op> {
def _B : sve_int_index_ir<0b00, asm, ZPR8, GPR32, simm5_8b>;
def _H : sve_int_index_ir<0b01, asm, ZPR16, GPR32, simm5_16b>;
def _S : sve_int_index_ir<0b10, asm, ZPR32, GPR32, simm5_32b>;
def _D : sve_int_index_ir<0b11, asm, ZPR64, GPR64, simm5_64b>;

def : Pat<(nxv16i8 (op simm5_8b:$imm5, GPR32:$Rm)),
(!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, GPR32:$Rm)>;
def : Pat<(nxv8i16 (op simm5_16b:$imm5, GPR32:$Rm)),
(!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, GPR32:$Rm)>;
def : Pat<(nxv4i32 (op simm5_32b:$imm5, GPR32:$Rm)),
(!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, GPR32:$Rm)>;
def : Pat<(nxv2i64 (op simm5_64b:$imm5, GPR64:$Rm)),
(!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, GPR64:$Rm)>;
}

class sve_int_index_ri<bits<2> sz8_64, string asm, ZPRRegOp zprty,
Expand All @@ -4434,11 +4452,20 @@ class sve_int_index_ri<bits<2> sz8_64, string asm, ZPRRegOp zprty,
let Inst{4-0} = Zd;
}

multiclass sve_int_index_ri<string asm> {
def _B : sve_int_index_ri<0b00, asm, ZPR8, GPR32, simm5_32b>;
def _H : sve_int_index_ri<0b01, asm, ZPR16, GPR32, simm5_32b>;
multiclass sve_int_index_ri<string asm, SDPatternOperator op> {
def _B : sve_int_index_ri<0b00, asm, ZPR8, GPR32, simm5_8b>;
def _H : sve_int_index_ri<0b01, asm, ZPR16, GPR32, simm5_16b>;
def _S : sve_int_index_ri<0b10, asm, ZPR32, GPR32, simm5_32b>;
def _D : sve_int_index_ri<0b11, asm, ZPR64, GPR64, simm5_64b>;

def : Pat<(nxv16i8 (op GPR32:$Rm, simm5_8b:$imm5)),
(!cast<Instruction>(NAME # "_B") GPR32:$Rm, simm5_8b:$imm5)>;
def : Pat<(nxv8i16 (op GPR32:$Rm, simm5_16b:$imm5)),
(!cast<Instruction>(NAME # "_H") GPR32:$Rm, simm5_16b:$imm5)>;
def : Pat<(nxv4i32 (op GPR32:$Rm, simm5_32b:$imm5)),
(!cast<Instruction>(NAME # "_S") GPR32:$Rm, simm5_32b:$imm5)>;
def : Pat<(nxv2i64 (op GPR64:$Rm, simm5_64b:$imm5)),
(!cast<Instruction>(NAME # "_D") GPR64:$Rm, simm5_64b:$imm5)>;
}

class sve_int_index_rr<bits<2> sz8_64, string asm, ZPRRegOp zprty,
Expand All @@ -4458,11 +4485,16 @@ class sve_int_index_rr<bits<2> sz8_64, string asm, ZPRRegOp zprty,
let Inst{4-0} = Zd;
}

multiclass sve_int_index_rr<string asm> {
multiclass sve_int_index_rr<string asm, SDPatternOperator op> {
def _B : sve_int_index_rr<0b00, asm, ZPR8, GPR32>;
def _H : sve_int_index_rr<0b01, asm, ZPR16, GPR32>;
def _S : sve_int_index_rr<0b10, asm, ZPR32, GPR32>;
def _D : sve_int_index_rr<0b11, asm, ZPR64, GPR64>;

def : SVE_2_Op_Pat<nxv16i8, op, i32, i32, !cast<Instruction>(NAME # _B)>;
def : SVE_2_Op_Pat<nxv8i16, op, i32, i32, !cast<Instruction>(NAME # _H)>;
def : SVE_2_Op_Pat<nxv4i32, op, i32, i32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv2i64, op, i64, i64, !cast<Instruction>(NAME # _D)>;
}
//
//===----------------------------------------------------------------------===//
Expand Down

0 comments on commit 633db60

Please sign in to comment.