Skip to content

Commit

Permalink
[AIE2] Implement unmerging for 32-bit vectors
Browse files Browse the repository at this point in the history
  • Loading branch information
ValentijnvdBeek committed May 31, 2024
1 parent fbdec8c commit cab4df9
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 1 deletion.
46 changes: 45 additions & 1 deletion llvm/lib/Target/AIE/AIELegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,47 @@ bool AIELegalizerInfo::pack32BitVector(LegalizerHelper &Helper,
return true;
}

bool AIELegalizerInfo::unpack32BitVector(LegalizerHelper &Helper,
MachineInstr &MI,
Register SourceReg) const {
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();

const LLT SourceRegTy = MRI.getType(SourceReg);
assert(SourceRegTy.getSizeInBits() == 32 &&
"cannot pack or unpack vectors larger or smaller than 32-bit");

const LLT S32 = LLT::scalar(32);
unsigned Offset = 0;
Register DstCastReg = MRI.createGenericVirtualRegister(S32);

MachineOperand *Operand = MI.operands_begin(),
*OperandEnd = MI.operands_end() - 1;
const LLT RegTy = MRI.getType(Operand->getReg());
MIRBuilder.buildBitcast(DstCastReg, SourceReg);
while (Operand != OperandEnd) {
Register DestinationOperand = Operand->getReg();
// Avoid a useless shift for the first element, since it doesn't get
// optimized out in O0.
if (Offset != 0) {
const MachineInstrBuilder ShiftConstant =
MIRBuilder.buildConstant(S32, Offset);
const MachineInstrBuilder Masked =
MIRBuilder.buildLShr(S32, DstCastReg, ShiftConstant);
MIRBuilder.buildTrunc(DestinationOperand, Masked);

} else {
MIRBuilder.buildTrunc(DestinationOperand, DstCastReg);
}

Offset += RegTy.getScalarSizeInBits();
++Operand;
}

MI.eraseFromParent();
return true;
}

bool AIELegalizerInfo::legalizeG_BUILD_VECTOR(LegalizerHelper &Helper,
MachineInstr &MI) const {
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
Expand Down Expand Up @@ -612,7 +653,7 @@ bool AIELegalizerInfo::legalizeG_BUILD_VECTOR(LegalizerHelper &Helper,
bool AIELegalizerInfo::legalizeG_UNMERGE_VALUES(LegalizerHelper &Helper,
MachineInstr &MI) const {
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
const MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();

const Register FirstReg = MI.getOperand(0).getReg();
const Register LastReg = MI.getOperand(MI.getNumOperands() - 1).getReg();
Expand All @@ -630,6 +671,9 @@ bool AIELegalizerInfo::legalizeG_UNMERGE_VALUES(LegalizerHelper &Helper,
assert(CurrentTy.isScalar() &&
"this operation is only supported for scalar types");

if (LastTy.getSizeInBits() == 32)
return unpack32BitVector(Helper, MI, LastReg);

// We build the constant ourselves since the default behaviour
// of the builtin is to create 64-bit constants.
const MachineInstrBuilder CurrentIndex =
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AIE/AIELegalizerInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class AIELegalizerInfo : public LegalizerInfo {
// Helper functions for legalization
bool pack32BitVector(LegalizerHelper &Helper, MachineInstr &MI,
Register SourceReg) const;
bool unpack32BitVector(LegalizerHelper &Helper, MachineInstr &MI,
Register SourceReg) const;
};
} // end namespace llvm
#endif
98 changes: 98 additions & 0 deletions llvm/test/CodeGen/AIE/aie2/GlobalISel/legalize-unmerge-values.mir
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,101 @@ body: |
%1(s8), %2(s8), %3(s8), %4(s8), %5(s8), %6(s8), %7(s8), %8(s8), %9(s8), %10(s8), %11(s8), %12(s8), %13(s8), %14(s8), %15(s8), %16(s8), %17(s8), %18(s8), %19(s8), %20(s8), %21(s8), %22(s8), %23(s8), %24(s8), %25(s8), %26(s8), %27(s8), %28(s8), %29(s8), %30(s8), %31(s8), %32(s8) = G_UNMERGE_VALUES %0(<32 x s8>)
%33(s32) = G_SEXT %8(s8)
PseudoRET implicit $lr, implicit %33
...
---
name: test_unmerge_v2s16
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
- { id: 2, class: _, preferred-register: '' }
- { id: 3, class: _, preferred-register: '' }
- { id: 4, class: _, preferred-register: '' }
- { id: 5, class: _, preferred-register: '' }
- { id: 6, class: _, preferred-register: '' }
legalized: false
body: |
bb.0.entry:
liveins: $r0
; CHECK-LABEL: name: test_unmerge_v2s16
; CHECK: liveins: $r0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $r0
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<2 x s16>)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[BITCAST]], [[C]](s32)
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[LSHR]], 16
; CHECK-NEXT: PseudoRET implicit $lr, implicit [[SEXT_INREG]](s32)
%0:_(<2 x s16>) = COPY $r0
%1(s16), %2(s16) = G_UNMERGE_VALUES %0(<2 x s16>)
%3(s32) = G_SEXT %2(s16)
PseudoRET implicit $lr, implicit %3
...
---
name: test_unmerge_v4s8
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
- { id: 2, class: _, preferred-register: '' }
- { id: 3, class: _, preferred-register: '' }
- { id: 4, class: _, preferred-register: '' }
- { id: 5, class: _, preferred-register: '' }
- { id: 6, class: _, preferred-register: '' }
- { id: 7, class: _, preferred-register: '' }
- { id: 8, class: _, preferred-register: '' }
legalized: false
body: |
bb.0.entry:
liveins: $r0
; CHECK-LABEL: name: test_unmerge_v4s8
; CHECK: liveins: $r0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s8>) = COPY $r0
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<4 x s8>)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[BITCAST]], [[C]](s32)
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[LSHR]], 8
; CHECK-NEXT: PseudoRET implicit $lr, implicit [[SEXT_INREG]](s32)
%0:_(<4 x s8>) = COPY $r0
%1(s8), %2(s8), %3(s8), %4(s8) = G_UNMERGE_VALUES %0(<4 x s8>)
%5(s32) = G_SEXT %4(s8)
PseudoRET implicit $lr, implicit %5
...
---
name: test_unmerge_32bit_order
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
- { id: 2, class: _, preferred-register: '' }
- { id: 3, class: _, preferred-register: '' }
- { id: 4, class: _, preferred-register: '' }
- { id: 5, class: _, preferred-register: '' }
- { id: 6, class: _, preferred-register: '' }
- { id: 7, class: _, preferred-register: '' }
- { id: 8, class: _, preferred-register: '' }
legalized: false
body: |
bb.0.entry:
liveins: $r0
; CHECK-LABEL: name: test_unmerge_32bit_order
; CHECK: liveins: $r0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s8>) = COPY $r0
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<4 x s8>)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[BITCAST]], [[C]](s32)
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[BITCAST]], [[C1]](s32)
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
; CHECK-NEXT: [[LSHR2:%[0-9]+]]:_(s32) = G_LSHR [[BITCAST]], [[C2]](s32)
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[BITCAST]], 8
; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[LSHR]], 8
; CHECK-NEXT: [[SEXT_INREG2:%[0-9]+]]:_(s32) = G_SEXT_INREG [[LSHR1]], 8
; CHECK-NEXT: [[SEXT_INREG3:%[0-9]+]]:_(s32) = G_SEXT_INREG [[LSHR2]], 8
; CHECK-NEXT: PseudoRET implicit $lr, implicit [[SEXT_INREG]](s32), implicit [[SEXT_INREG1]](s32), implicit [[SEXT_INREG2]](s32), implicit [[SEXT_INREG3]](s32)
%0:_(<4 x s8>) = COPY $r0
%1(s8), %2(s8), %3(s8), %4(s8) = G_UNMERGE_VALUES %0(<4 x s8>)
%5(s32) = G_SEXT %1(s8)
%6(s32) = G_SEXT %2(s8)
%7(s32) = G_SEXT %3(s8)
%8(s32) = G_SEXT %4(s8)
PseudoRET implicit $lr, implicit %5, implicit %6, implicit %7, implicit %8

0 comments on commit cab4df9

Please sign in to comment.