diff --git a/llvm/lib/Target/AIE/AIE2InstrPatterns.td b/llvm/lib/Target/AIE/AIE2InstrPatterns.td index 0d7098ecd861..d363f40bab53 100644 --- a/llvm/lib/Target/AIE/AIE2InstrPatterns.td +++ b/llvm/lib/Target/AIE/AIE2InstrPatterns.td @@ -961,6 +961,22 @@ def : Concat256; def : Concat512; def : Concat1024; +// concat_vector generic opcode +def : Pat<(v16i32 (concat_vectors (v8i32 VEC256:$src0), (v8i32 VEC256:$src1))), + (v16i32 (REG_SEQUENCE VEC512, VEC256:$src0, sub_256_lo, VEC256:$src1, sub_256_hi))>; +def : Pat<(v32i32 (concat_vectors (v16i32 VEC512:$src0), (v16i32 VEC512:$src1))), + (v32i32 (REG_SEQUENCE VEC1024, VEC512:$src0, sub_512_lo, VEC512:$src1, sub_512_hi))>; + +def : Pat<(v32i16 (concat_vectors (v16i16 VEC256:$src0), (v16i16 VEC256:$src1))), + (v32i16 (REG_SEQUENCE VEC512, VEC256:$src0, sub_256_lo, VEC256:$src1, sub_256_hi))>; +def : Pat<(v64i16 (concat_vectors (v32i16 VEC512:$src0), (v32i16 VEC512:$src1))), + (v64i16 (REG_SEQUENCE VEC1024, VEC512:$src0, sub_512_lo, VEC512:$src1, sub_512_hi))>; + +def : Pat<(v64i8 (concat_vectors (v32i8 VEC256:$src0), (v32i8 VEC256:$src1))), + (v64i8 (REG_SEQUENCE VEC512, VEC256:$src0, sub_256_lo, VEC256:$src1, sub_256_hi))>; +def : Pat<(v128i8 (concat_vectors (v64i8 VEC512:$src0), (v64i8 VEC512:$src1))), + (v128i8 (REG_SEQUENCE VEC1024, VEC512:$src0, sub_512_lo, VEC512:$src1, sub_512_hi))>; + // Extract def : Pat<(int_aie2_ext_I256_I512 VEC512:$src, 0x0), (v8i32 (EXTRACT_SUBREG VEC512:$src, sub_256_lo))>; diff --git a/llvm/lib/Target/AIE/AIE2InstructionSelector.cpp b/llvm/lib/Target/AIE/AIE2InstructionSelector.cpp index 4e3b646be96b..b55cd12e8891 100644 --- a/llvm/lib/Target/AIE/AIE2InstructionSelector.cpp +++ b/llvm/lib/Target/AIE/AIE2InstructionSelector.cpp @@ -142,7 +142,6 @@ class AIE2InstructionSelector : public InstructionSelector { bool isWrite); bool selectG_AIE_ADD_VECTOR_ELT_LEFT(MachineInstr &I, MachineRegisterInfo &MRI); - bool selectG_CONCAT_VECTORS(MachineInstr &I, MachineRegisterInfo &MRI); bool selectG_BRCOND(MachineInstr &I, MachineRegisterInfo &MRI); bool selectG_BRINDIRECT(MachineInstr &I, MachineRegisterInfo &MRI); bool selectG_JUMP_TABLE(MachineInstr &I, MachineRegisterInfo &MRI); @@ -742,8 +741,6 @@ bool AIE2InstructionSelector::select(MachineInstr &I) { return selectG_UNMERGE_VALUES(I, MRI); case AIE2::G_AIE_ADD_VECTOR_ELT_LEFT: return selectG_AIE_ADD_VECTOR_ELT_LEFT(I, MRI); - case G_CONCAT_VECTORS: - return selectG_CONCAT_VECTORS(I, MRI); case AIE2::G_AIE_OFFSET_STORE: case AIE2::G_AIE_POSTINC_STORE: case AIE2::G_AIE_POSTINC_2D_STORE: @@ -843,52 +840,6 @@ bool AIE2InstructionSelector::selectG_AIE_ADD_VECTOR_ELT_LEFT( return constrainSelectedInstRegOperands(MI, TII, TRI, RBI); } -// WIP: Implement this as a tablegen pattern instead, it is very similar to the -// definition used for instrinsics. -bool AIE2InstructionSelector::selectG_CONCAT_VECTORS(MachineInstr &I, - MachineRegisterInfo &MRI) { - const Register DstVecReg = I.getOperand(0).getReg(); - const Register Src1VecReg = I.getOperand(1).getReg(); - const Register Src2VecReg = I.getOperand(2).getReg(); - - const unsigned DstVecSize = MRI.getType(DstVecReg).getSizeInBits(); - const unsigned Src1VecSize = MRI.getType(Src1VecReg).getSizeInBits(); - const unsigned Src2VecSize = MRI.getType(Src2VecReg).getSizeInBits(); - - assert( - Src1VecSize == Src2VecSize && (DstVecSize == 2 * Src1VecSize) && - (I.getNumOperands() == 3) && - "Vectors can only be concatenated if the size of the two operands are " - "the same and are, if added together, equal to the destination vector"); - - // We are using a Reg Sequence here instead of copies since using - // subregisters causes the SSA violations to occur since it sees %x_hi and - // %x_lo as the same register. - MachineInstrBuilder RegSeq; - const TargetRegisterClass *TRC = nullptr; - if (DstVecSize == 512) { - RegSeq = MIB.buildInstr(AIE2::REG_SEQUENCE, {DstVecReg}, {}) - .addReg(Src1VecReg) - .addImm(AIE2::sub_256_lo) - .addReg(Src2VecReg) - .addImm(AIE2::sub_256_hi); - TRC = &AIE2::VEC512RegClass; - } else if (DstVecSize == 1024) { - RegSeq = MIB.buildInstr(AIE2::REG_SEQUENCE, {DstVecReg}, {}) - .addReg(Src1VecReg) - .addImm(AIE2::sub_512_lo) - .addReg(Src2VecReg) - .addImm(AIE2::sub_512_hi); - TRC = &AIE2::VEC1024RegClass; - } - - constrainOperandRegClass(*MF, TRI, MRI, TII, RBI, *RegSeq, *TRC, - RegSeq->getOperand(0)); - - I.eraseFromParent(); - return true; -} - bool AIE2InstructionSelector::selectG_BRCOND(MachineInstr &I, MachineRegisterInfo &MRI) { Register CondReg = I.getOperand(0).getReg(); diff --git a/llvm/test/CodeGen/AIE/aie2/GlobalISel/inst-select-concat-vectors.mir b/llvm/test/CodeGen/AIE/aie2/GlobalISel/inst-select-concat-vectors.mir index a1d7d199fbe2..f29a0296588c 100644 --- a/llvm/test/CodeGen/AIE/aie2/GlobalISel/inst-select-concat-vectors.mir +++ b/llvm/test/CodeGen/AIE/aie2/GlobalISel/inst-select-concat-vectors.mir @@ -18,8 +18,8 @@ stack: body: | bb.0.entry: ; CHECK-LABEL: name: vconcat_1024 - ; CHECK: [[DEF:%[0-9]+]]:vec512 = IMPLICIT_DEF - ; CHECK-NEXT: [[DEF1:%[0-9]+]]:vec512 = IMPLICIT_DEF + ; CHECK: [[DEF:%[0-9]+]]:exe = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:exo = IMPLICIT_DEF ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vec1024 = REG_SEQUENCE [[DEF]], %subreg.sub_512_lo, [[DEF1]], %subreg.sub_512_hi ; CHECK-NEXT: PseudoRET implicit $lr, implicit [[REG_SEQUENCE]] %0:vregbank(<16 x s32>) = G_IMPLICIT_DEF @@ -29,7 +29,7 @@ body: | ... --- -name: vconcat_512 +name: vconcat_512_32 legalized: true regBankSelected: true tracksRegLiveness: true @@ -37,12 +37,92 @@ stack: - { id: 0, name: "", size: 128, alignment: 32 } body: | bb.0.entry: - ; CHECK-LABEL: name: vconcat_512 - ; CHECK: [[DEF:%[0-9]+]]:vec256 = IMPLICIT_DEF - ; CHECK-NEXT: [[DEF1:%[0-9]+]]:vec256 = IMPLICIT_DEF + ; CHECK-LABEL: name: vconcat_512_32 + ; CHECK: [[DEF:%[0-9]+]]:ewl = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:ewh = IMPLICIT_DEF ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vec512 = REG_SEQUENCE [[DEF]], %subreg.sub_256_lo, [[DEF1]], %subreg.sub_256_hi ; CHECK-NEXT: PseudoRET implicit $lr, implicit [[REG_SEQUENCE]] %0:vregbank(<8 x s32>) = G_IMPLICIT_DEF %1:vregbank(<8 x s32>) = G_IMPLICIT_DEF %2:vregbank(<16 x s32>) = G_CONCAT_VECTORS %0(<8 x s32>), %1(<8 x s32>) PseudoRET implicit $lr, implicit %2 +... + +--- +name: vconcat_512_16 +legalized: true +regBankSelected: true +tracksRegLiveness: true +stack: + - { id: 0, name: "", size: 128, alignment: 32 } +body: | + bb.0.entry: + ; CHECK-LABEL: name: vconcat_512_16 + ; CHECK: [[DEF:%[0-9]+]]:ewl = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:ewh = IMPLICIT_DEF + ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vec512 = REG_SEQUENCE [[DEF]], %subreg.sub_256_lo, [[DEF1]], %subreg.sub_256_hi + ; CHECK-NEXT: PseudoRET implicit $lr, implicit [[REG_SEQUENCE]] + %0:vregbank(<16 x s16>) = G_IMPLICIT_DEF + %1:vregbank(<16 x s16>) = G_IMPLICIT_DEF + %2:vregbank(<32 x s16>) = G_CONCAT_VECTORS %0(<16 x s16>), %1(<16 x s16>) + PseudoRET implicit $lr, implicit %2 +... + +--- +name: vconcat_1024_16 +legalized: true +regBankSelected: true +tracksRegLiveness: true +stack: + - { id: 0, name: "", size: 128, alignment: 32 } +body: | + bb.0.entry: + ; CHECK-LABEL: name: vconcat_1024_16 + ; CHECK: [[DEF:%[0-9]+]]:exe = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:exo = IMPLICIT_DEF + ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vec1024 = REG_SEQUENCE [[DEF]], %subreg.sub_512_lo, [[DEF1]], %subreg.sub_512_hi + ; CHECK-NEXT: PseudoRET implicit $lr, implicit [[REG_SEQUENCE]] + %0:vregbank(<32 x s16>) = G_IMPLICIT_DEF + %1:vregbank(<32 x s16>) = G_IMPLICIT_DEF + %2:vregbank(<64 x s16>) = G_CONCAT_VECTORS %0(<32 x s16>), %1(<32 x s16>) + PseudoRET implicit $lr, implicit %2 +... + +--- +name: vconcat_512_8 +legalized: true +regBankSelected: true +tracksRegLiveness: true +stack: + - { id: 0, name: "", size: 128, alignment: 32 } +body: | + bb.0.entry: + ; CHECK-LABEL: name: vconcat_512_8 + ; CHECK: [[DEF:%[0-9]+]]:ewl = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:ewh = IMPLICIT_DEF + ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vec512 = REG_SEQUENCE [[DEF]], %subreg.sub_256_lo, [[DEF1]], %subreg.sub_256_hi + ; CHECK-NEXT: PseudoRET implicit $lr, implicit [[REG_SEQUENCE]] + %0:vregbank(<32 x s8>) = G_IMPLICIT_DEF + %1:vregbank(<32 x s8>) = G_IMPLICIT_DEF + %2:vregbank(<64 x s8>) = G_CONCAT_VECTORS %0(<32 x s8>), %1(<32 x s8>) + PseudoRET implicit $lr, implicit %2 +... + +--- +name: vconcat_1024_8 +legalized: true +regBankSelected: true +tracksRegLiveness: true +stack: + - { id: 0, name: "", size: 128, alignment: 32 } +body: | + bb.0.entry: + ; CHECK-LABEL: name: vconcat_1024_8 + ; CHECK: [[DEF:%[0-9]+]]:exe = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:exo = IMPLICIT_DEF + ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vec1024 = REG_SEQUENCE [[DEF]], %subreg.sub_512_lo, [[DEF1]], %subreg.sub_512_hi + ; CHECK-NEXT: PseudoRET implicit $lr, implicit [[REG_SEQUENCE]] + %0:vregbank(<64 x s8>) = G_IMPLICIT_DEF + %1:vregbank(<64 x s8>) = G_IMPLICIT_DEF + %2:vregbank(<128 x s8>) = G_CONCAT_VECTORS %0(<64 x s8>), %1(<64 x s8>) + PseudoRET implicit $lr, implicit %2