Skip to content

Commit

Permalink
[AIE2] Support for 64-bit G_BUILD_VECTOR and G_UNMERGE_VALUES
Browse files Browse the repository at this point in the history
  • Loading branch information
ValentijnvdBeek committed Jun 17, 2024
1 parent 118f973 commit d65813c
Show file tree
Hide file tree
Showing 4 changed files with 253 additions and 32 deletions.
62 changes: 33 additions & 29 deletions llvm/lib/Target/AIE/AIELegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static LegalityPredicate isValidVectorAIE2(const unsigned TypeIdx) {
return [=](const LegalityQuery &Query) {
const LLT DstTy = Query.Types[TypeIdx];
const unsigned DstSize = DstTy.getSizeInBits();
return DstTy.isVector() && (DstSize == 32 || DstSize > 64);
return DstTy.isVector() && (DstSize == 32 || DstSize >= 64);
};
}

Expand Down Expand Up @@ -551,44 +551,46 @@ bool AIELegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
llvm_unreachable("Un-expected custom legalization");
}

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

const LLT SourceRegTy = MRI.getType(SourceReg);
const Register DstReg = MI.getOperand(0).getReg();
assert(SourceRegTy.getSizeInBits() == 32 &&
"cannot pack vectors larger or smaller than 32-bit");
assert(SourceRegTy.getSizeInBits() == 32 ||
SourceRegTy.getSizeInBits() == 64 &&
"can only pack 32- and 64-bit vectors");

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

// Skip the destination operand since that is where we are writing to.
MachineOperand *Operand = MI.operands_begin() + 1,
*OperandEnd = MI.operands_end();
MIRBuilder.buildConstant(DstCastReg, 0);

const LLT RegTy = MRI.getType(DstReg);
const LLT RegTy = MRI.getType(Operand->getReg());
while (Operand != OperandEnd) {
Register DestinationOperand = Operand->getReg();

if (RegTy.getScalarSizeInBits() != 32) {
const Register TmpReg32 = MRI.createGenericVirtualRegister(S32);
MIRBuilder.buildInstr(AIE2::G_ZEXT, {TmpReg32}, {DestinationOperand});
DestinationOperand = TmpReg32;
const LLT S32 = LLT::scalar(32);
if (RegTy != STy) {
const Register TmpReg = MRI.createGenericVirtualRegister(STy);
MIRBuilder.buildInstr(AIE2::G_ZEXT, {TmpReg}, {DestinationOperand});
DestinationOperand = TmpReg;
}

// Avoid a useless shift for the first element, since it doesn't get
// optimized out in O0.
const Register AccumulatorReg = MRI.createGenericVirtualRegister(S32);
const Register AccumulatorReg = MRI.createGenericVirtualRegister(STy);

if (Offset != 0) {
const MachineInstrBuilder ShiftConstant =
MIRBuilder.buildConstant(S32, Offset);
const MachineInstrBuilder Masked =
MIRBuilder.buildShl(S32, DestinationOperand, ShiftConstant);
MIRBuilder.buildShl(STy, DestinationOperand, ShiftConstant);
MIRBuilder.buildOr(AccumulatorReg, DstCastReg, Masked);
} else {
MIRBuilder.buildOr(AccumulatorReg, DstCastReg, DestinationOperand);
Expand All @@ -604,19 +606,20 @@ bool AIELegalizerInfo::pack32BitVector(LegalizerHelper &Helper,
return true;
}

bool AIELegalizerInfo::unpack32BitVector(LegalizerHelper &Helper,
MachineInstr &MI,
Register SourceReg) const {
bool AIELegalizerInfo::unpackBitVector(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 unpack vectors larger or smaller than 32-bit");
assert(SourceRegTy.getSizeInBits() == 32 ||
SourceRegTy.getSizeInBits() == 64 &&
"can only unpack 32- and 64-bit vectors");

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

MachineOperand *Operand = MI.operands_begin(),
*OperandEnd = MI.operands_end() - 1;
Expand All @@ -627,10 +630,11 @@ bool AIELegalizerInfo::unpack32BitVector(LegalizerHelper &Helper,
// Avoid a useless shift for the first element, since it doesn't get
// optimized out in O0.
if (Offset != 0) {
const LLT S32 = LLT::scalar(32);
const MachineInstrBuilder ShiftConstant =
MIRBuilder.buildConstant(S32, Offset);
const MachineInstrBuilder Masked =
MIRBuilder.buildLShr(S32, DstCastReg, ShiftConstant);
MIRBuilder.buildLShr(STy, DstCastReg, ShiftConstant);
MIRBuilder.buildTrunc(DestinationOperand, Masked);

} else {
Expand Down Expand Up @@ -658,13 +662,13 @@ bool AIELegalizerInfo::legalizeG_BUILD_VECTOR(LegalizerHelper &Helper,
const unsigned EltSize = DstVecEltTy.getScalarSizeInBits();
assert((EltSize == 8 || EltSize == 16 || EltSize == 32) &&
"non-existent integer size");
assert(DstVecSize == 32 || (DstVecSize > 64 && DstVecSize <= 1024 &&
"non-native vectors are not supported"));
assert(DstVecSize >= 32 && DstVecSize <= 1024 &&
"non-native vectors are not supported");
assert(DstVecSize < 1024 && "vadd takes a 512-bit argument");

// If our vector is 32-bit we can store it as packed integer vector
if (DstVecSize == 32)
return pack32BitVector(Helper, MI, DstReg);
if (DstVecSize == 32 || DstVecSize == 64)
return packBitVector(Helper, MI, DstReg);

// We are using an undef since we are building over multiple instructions
const TypeSize VecEltTySize = DstVecEltTy.getSizeInBits();
Expand Down Expand Up @@ -724,8 +728,8 @@ bool AIELegalizerInfo::legalizeG_UNMERGE_VALUES(LegalizerHelper &Helper,
LastTy.getSizeInBits() &&
"This operation is only supported for vectors");

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

// Pad vectors of 128-bit vectors to 256-bit
Register TargetReg = LastReg;
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/AIE/AIELegalizerInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ class AIELegalizerInfo : public LegalizerInfo {
bool legalizeG_FADDSUB(LegalizerHelper &Helper, MachineInstr &MI) const;

// Helper functions for legalization
bool pack32BitVector(LegalizerHelper &Helper, MachineInstr &MI,
bool packBitVector(LegalizerHelper &Helper, MachineInstr &MI,
Register SourceReg) const;
bool unpackBitVector(LegalizerHelper &Helper, MachineInstr &MI,
Register SourceReg) const;
bool unpack32BitVector(LegalizerHelper &Helper, MachineInstr &MI,
Register SourceReg) const;
};
} // end namespace llvm
#endif
108 changes: 108 additions & 0 deletions llvm/test/CodeGen/AIE/aie2/GlobalISel/legalize-build-vector.mir
Original file line number Diff line number Diff line change
Expand Up @@ -661,3 +661,111 @@ body: |
%5:_(s8) = G_TRUNC %1(s32)
%6:_(<4 x s8>) = G_BUILD_VECTOR %2(s8), %3(s8), %4(s8), %5(s8)
PseudoRET implicit $lr, implicit %6
...

---
name: test_build_vector_64_16
body: |
bb.1.entry:
; CHECK-LABEL: name: test_build_vector_64_16
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[C]], [[C5]]
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[DEF]], [[C4]]
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[C4]], [[AND]]
; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s32) = G_OR [[C4]], [[AND1]]
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[C1]], [[C5]]
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[DEF]], [[C4]]
; CHECK-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[AND2]], [[C6]](s32)
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[AND3]], [[C6]](s32)
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[C6]](s32)
; CHECK-NEXT: [[OR2:%[0-9]+]]:_(s32) = G_OR [[SHL1]], [[LSHR]]
; CHECK-NEXT: [[OR3:%[0-9]+]]:_(s32) = G_OR [[OR]], [[SHL]]
; CHECK-NEXT: [[OR4:%[0-9]+]]:_(s32) = G_OR [[OR1]], [[OR2]]
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s32) = G_AND [[C2]], [[C5]]
; CHECK-NEXT: [[OR5:%[0-9]+]]:_(s32) = G_OR [[OR3]], [[C4]]
; CHECK-NEXT: [[OR6:%[0-9]+]]:_(s32) = G_OR [[OR4]], [[AND4]]
; CHECK-NEXT: [[AND5:%[0-9]+]]:_(s32) = G_AND [[C3]], [[C5]]
; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[AND5]], [[C6]](s32)
; CHECK-NEXT: [[OR7:%[0-9]+]]:_(s32) = G_OR [[OR5]], [[C4]]
; CHECK-NEXT: [[OR8:%[0-9]+]]:_(s32) = G_OR [[OR6]], [[SHL2]]
; CHECK-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[OR7]](s32), [[OR8]](s32)
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<4 x s16>) = G_BITCAST [[MV]](s64)
; CHECK-NEXT: PseudoRET implicit $lr, implicit [[BITCAST]](<4 x s16>)
%0:_(s16) = G_CONSTANT i16 1
%1:_(s16) = G_CONSTANT i16 2
%2:_(s16) = G_CONSTANT i16 3
%3:_(s16) = G_CONSTANT i16 4
%4:_(<4 x s16>) = G_BUILD_VECTOR %0(s16), %1(s16), %2(s16), %3(s16)
PseudoRET implicit $lr, implicit %4
...

---
name: test_build_vector_64_8
body: |
bb.1.entry:
; CHECK-LABEL: name: test_build_vector_64_8
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[C]], [[C5]]
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[DEF]], [[C4]]
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[C4]], [[AND]]
; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s32) = G_OR [[C4]], [[AND1]]
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[C1]], [[C5]]
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[DEF]], [[C4]]
; CHECK-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[AND2]], [[C6]](s32)
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[AND3]], [[C6]](s32)
; CHECK-NEXT: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[C7]](s32)
; CHECK-NEXT: [[OR2:%[0-9]+]]:_(s32) = G_OR [[SHL1]], [[LSHR]]
; CHECK-NEXT: [[OR3:%[0-9]+]]:_(s32) = G_OR [[OR]], [[SHL]]
; CHECK-NEXT: [[OR4:%[0-9]+]]:_(s32) = G_OR [[OR1]], [[OR2]]
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s32) = G_AND [[C2]], [[C5]]
; CHECK-NEXT: [[AND5:%[0-9]+]]:_(s32) = G_AND [[DEF]], [[C4]]
; CHECK-NEXT: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[AND4]], [[C8]](s32)
; CHECK-NEXT: [[SHL3:%[0-9]+]]:_(s32) = G_SHL [[AND5]], [[C8]](s32)
; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[AND4]], [[C8]](s32)
; CHECK-NEXT: [[OR5:%[0-9]+]]:_(s32) = G_OR [[SHL3]], [[LSHR1]]
; CHECK-NEXT: [[OR6:%[0-9]+]]:_(s32) = G_OR [[OR3]], [[SHL2]]
; CHECK-NEXT: [[OR7:%[0-9]+]]:_(s32) = G_OR [[OR4]], [[OR5]]
; CHECK-NEXT: [[AND6:%[0-9]+]]:_(s32) = G_AND [[C3]], [[C5]]
; CHECK-NEXT: [[AND7:%[0-9]+]]:_(s32) = G_AND [[DEF]], [[C4]]
; CHECK-NEXT: [[SHL4:%[0-9]+]]:_(s32) = G_SHL [[AND6]], [[C7]](s32)
; CHECK-NEXT: [[SHL5:%[0-9]+]]:_(s32) = G_SHL [[AND7]], [[C7]](s32)
; CHECK-NEXT: [[LSHR2:%[0-9]+]]:_(s32) = G_LSHR [[AND6]], [[C6]](s32)
; CHECK-NEXT: [[OR8:%[0-9]+]]:_(s32) = G_OR [[SHL5]], [[LSHR2]]
; CHECK-NEXT: [[OR9:%[0-9]+]]:_(s32) = G_OR [[OR6]], [[SHL4]]
; CHECK-NEXT: [[OR10:%[0-9]+]]:_(s32) = G_OR [[OR7]], [[OR8]]
; CHECK-NEXT: [[OR11:%[0-9]+]]:_(s32) = G_OR [[OR9]], [[C4]]
; CHECK-NEXT: [[OR12:%[0-9]+]]:_(s32) = G_OR [[OR10]], [[AND6]]
; CHECK-NEXT: [[SHL6:%[0-9]+]]:_(s32) = G_SHL [[AND4]], [[C6]](s32)
; CHECK-NEXT: [[OR13:%[0-9]+]]:_(s32) = G_OR [[OR11]], [[C4]]
; CHECK-NEXT: [[OR14:%[0-9]+]]:_(s32) = G_OR [[OR12]], [[SHL6]]
; CHECK-NEXT: [[SHL7:%[0-9]+]]:_(s32) = G_SHL [[AND2]], [[C8]](s32)
; CHECK-NEXT: [[OR15:%[0-9]+]]:_(s32) = G_OR [[OR13]], [[C4]]
; CHECK-NEXT: [[OR16:%[0-9]+]]:_(s32) = G_OR [[OR14]], [[SHL7]]
; CHECK-NEXT: [[SHL8:%[0-9]+]]:_(s32) = G_SHL [[AND]], [[C7]](s32)
; CHECK-NEXT: [[OR17:%[0-9]+]]:_(s32) = G_OR [[OR15]], [[C4]]
; CHECK-NEXT: [[OR18:%[0-9]+]]:_(s32) = G_OR [[OR16]], [[SHL8]]
; CHECK-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[OR17]](s32), [[OR18]](s32)
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<8 x s8>) = G_BITCAST [[MV]](s64)
; CHECK-NEXT: PseudoRET implicit $lr, implicit [[BITCAST]](<8 x s8>)
%0:_(s8) = G_CONSTANT i8 1
%1:_(s8) = G_CONSTANT i8 2
%2:_(s8) = G_CONSTANT i8 3
%3:_(s8) = G_CONSTANT i8 4
%4:_(<8 x s8>) = G_BUILD_VECTOR %0(s8), %1(s8), %2(s8), %3(s8), %3(s8), %2(s8), %1(s8), %0(s8)
PseudoRET implicit $lr, implicit %4
109 changes: 109 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 @@ -525,3 +525,112 @@ body: |
%1(s32), %2(s32), %3(s32), %4(s32) = G_UNMERGE_VALUES %5(<4 x s32>)
PseudoRET implicit $lr, implicit %1, implicit %2, implicit %3, implicit %4
...
---
name: test_unmerge_v4s16
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: $l0
; CHECK-LABEL: name: test_unmerge_v4s16
; CHECK: liveins: $l0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $l0
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[COPY]](<4 x s16>)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]](s64)
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[UV1]], [[C]](s32)
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[LSHR]], 16
; CHECK-NEXT: PseudoRET implicit $lr, implicit [[SEXT_INREG]](s32)
%0:_(<4 x s16>) = COPY $l0
%1(s16), %2(s16), %3(s16), %4(s16) = G_UNMERGE_VALUES %0(<4 x s16>)
%5(s32) = G_SEXT %4(s16)
PseudoRET implicit $lr, implicit %5
...
---
name: test_unmerge_v8s8
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: '' }
- { id: 9, class: _, preferred-register: '' }

legalized: false
body: |
bb.0.entry:
liveins: $l0
; CHECK-LABEL: name: test_unmerge_v8s8
; CHECK: liveins: $l0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $l0
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[COPY]](<8 x s8>)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]](s64)
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[UV]], [[C1]](s32)
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[UV1]], [[C]](s32)
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[LSHR]], [[SHL]]
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[OR]], 8
; CHECK-NEXT: PseudoRET implicit $lr, implicit [[SEXT_INREG]](s32)
%0:_(<8 x s8>) = COPY $l0
%1(s8), %2(s8), %3(s8), %4(s8), %5(s8), %6(s8), %7(s8), %8(s8) = G_UNMERGE_VALUES %0(<8 x s8>)
%9(s32) = G_SEXT %4(s8)
PseudoRET implicit $lr, implicit %9
...
---
name: test_unmerge_64bit_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: $l0
; CHECK-LABEL: name: test_unmerge_64bit_order
; CHECK: liveins: $l0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $l0
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[COPY]](<4 x s16>)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]](s64)
; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[UV]], [[C]](s32)
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[UV1]], [[C]](s32)
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[LSHR]], [[SHL]]
; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]](s64)
; CHECK-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]](s64)
; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[UV5]], [[C]](s32)
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[BITCAST]](s64)
; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[TRUNC]], 16
; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[OR]], 16
; CHECK-NEXT: [[SEXT_INREG2:%[0-9]+]]:_(s32) = G_SEXT_INREG [[UV3]], 16
; CHECK-NEXT: [[SEXT_INREG3:%[0-9]+]]:_(s32) = G_SEXT_INREG [[LSHR1]], 16
; CHECK-NEXT: PseudoRET implicit $lr, implicit [[SEXT_INREG]](s32), implicit [[SEXT_INREG1]](s32), implicit [[SEXT_INREG2]](s32), implicit [[SEXT_INREG3]](s32)
%0:_(<4 x s16>) = COPY $l0
%1(s16), %2(s16), %3(s16), %4(s16) = G_UNMERGE_VALUES %0(<4 x s16>)
%5(s32) = G_SEXT %1(s16)
%6(s32) = G_SEXT %2(s16)
%7(s32) = G_SEXT %3(s16)
%8(s32) = G_SEXT %4(s16)
PseudoRET implicit $lr, implicit %5, implicit %6, implicit %7, implicit %8

0 comments on commit d65813c

Please sign in to comment.