Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AIE2] Support for 64-bit G_BUILD_VECTOR and G_UNMERGE_VALUES #77

Open
wants to merge 1 commit into
base: aie-public
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 34 additions & 30 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);
};
}

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) 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");
const LLT DstRegTy = MRI.getType(DstReg);
assert(DstRegTy.getSizeInBits() == 32 ||
DstRegTy.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) const {
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();

const Register SourceReg = MI.getOperand(MI.getNumOperands() - 1).getReg();
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);

// 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);

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

// Helper functions for legalization
bool pack32BitVector(LegalizerHelper &Helper, MachineInstr &MI,
Register SourceReg) const;
bool unpack32BitVector(LegalizerHelper &Helper, MachineInstr &MI,
Register SourceReg) const;
bool packBitVector(LegalizerHelper &Helper, MachineInstr &MI) const;
bool unpackBitVector(LegalizerHelper &Helper, MachineInstr &MI) 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
Loading