mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
GlobalISel: support G_TRUNC selection on AArch64.
Ahmed's patch again. llvm-svn: 284075
This commit is contained in:
parent
3df46ddb6d
commit
498e50998f
@ -41,6 +41,32 @@ AArch64InstructionSelector::AArch64InstructionSelector(
|
||||
: InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
|
||||
TRI(*STI.getRegisterInfo()), RBI(RBI) {}
|
||||
|
||||
// FIXME: This should be target-independent, inferred from the types declared
|
||||
// for each class in the bank.
|
||||
static const TargetRegisterClass *
|
||||
getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
|
||||
const RegisterBankInfo &RBI) {
|
||||
if (RB.getID() == AArch64::GPRRegBankID) {
|
||||
if (Ty.getSizeInBits() <= 32)
|
||||
return &AArch64::GPR32RegClass;
|
||||
if (Ty.getSizeInBits() == 64)
|
||||
return &AArch64::GPR64RegClass;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (RB.getID() == AArch64::FPRRegBankID) {
|
||||
if (Ty.getSizeInBits() == 32)
|
||||
return &AArch64::FPR32RegClass;
|
||||
if (Ty.getSizeInBits() == 64)
|
||||
return &AArch64::FPR64RegClass;
|
||||
if (Ty.getSizeInBits() == 128)
|
||||
return &AArch64::FPR128RegClass;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Check whether \p I is a currently unsupported binary operation:
|
||||
/// - it has an unsized type
|
||||
/// - an operand is not a vreg
|
||||
@ -633,6 +659,60 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
|
||||
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
|
||||
}
|
||||
|
||||
case TargetOpcode::G_TRUNC: {
|
||||
const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
|
||||
const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
|
||||
|
||||
const unsigned DstReg = I.getOperand(0).getReg();
|
||||
const unsigned SrcReg = I.getOperand(1).getReg();
|
||||
|
||||
const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
|
||||
const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
|
||||
|
||||
if (DstRB.getID() != SrcRB.getID()) {
|
||||
DEBUG(dbgs() << "G_TRUNC input/output on different banks\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DstRB.getID() == AArch64::GPRRegBankID) {
|
||||
const TargetRegisterClass *DstRC =
|
||||
getRegClassForTypeOnBank(DstTy, DstRB, RBI);
|
||||
if (!DstRC)
|
||||
return false;
|
||||
|
||||
const TargetRegisterClass *SrcRC =
|
||||
getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
|
||||
if (!SrcRC)
|
||||
return false;
|
||||
|
||||
if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
|
||||
!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
|
||||
DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DstRC == SrcRC) {
|
||||
// Nothing to be done
|
||||
} else if (DstRC == &AArch64::GPR32RegClass &&
|
||||
SrcRC == &AArch64::GPR64RegClass) {
|
||||
I.getOperand(1).setSubReg(AArch64::sub_32);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
I.setDesc(TII.get(TargetOpcode::COPY));
|
||||
return true;
|
||||
} else if (DstRB.getID() == AArch64::FPRRegBankID) {
|
||||
if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) {
|
||||
I.setDesc(TII.get(AArch64::XTNv4i16));
|
||||
constrainSelectedInstRegOperands(I, TII, TRI, RBI);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case TargetOpcode::G_ANYEXT: {
|
||||
const unsigned DstReg = I.getOperand(0).getReg();
|
||||
const unsigned SrcReg = I.getOperand(1).getReg();
|
||||
|
@ -104,6 +104,8 @@
|
||||
@var_got = external global i8
|
||||
define i8* @global_got() { ret i8* undef }
|
||||
|
||||
define void @trunc() { ret void }
|
||||
|
||||
define void @anyext_gpr() { ret void }
|
||||
define void @zext_gpr() { ret void }
|
||||
define void @sext_gpr() { ret void }
|
||||
@ -1767,6 +1769,41 @@ body: |
|
||||
%0(p0) = G_GLOBAL_VALUE @var_got
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: trunc
|
||||
name: trunc
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr32 }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr32 }
|
||||
# CHECK-NEXT: - { id: 2, class: gpr64 }
|
||||
# CHECK-NEXT: - { id: 3, class: gpr32 }
|
||||
# CHECK-NEXT: - { id: 4, class: gpr32 }
|
||||
registers:
|
||||
- { id: 0, class: gpr }
|
||||
- { id: 1, class: gpr }
|
||||
- { id: 2, class: gpr }
|
||||
- { id: 3, class: gpr }
|
||||
- { id: 4, class: gpr }
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: %1 = COPY %0
|
||||
# CHECK: %3 = COPY %2.sub_32
|
||||
# CHECK: %4 = COPY %2.sub_32
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %w0, %x0
|
||||
|
||||
%0(s32) = COPY %w0
|
||||
%1(s1) = G_TRUNC %0
|
||||
|
||||
%2(s64) = COPY %x0
|
||||
%3(s32) = G_TRUNC %2
|
||||
%4(s8) = G_TRUNC %2
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: anyext_gpr
|
||||
name: anyext_gpr
|
||||
|
Loading…
Reference in New Issue
Block a user