mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 14:47:00 +00:00
[AArch64][RegisterBankInfo] Add mapping for G_FPEXT.
This fixes http://llvm.org/PR32560. We were missing a description for half floating point type and as a result were using the FPR 32 mapping. Because of the size mismatch the generic code was complaining that the default mapping is not appropriate. Fix the mapping description so that the default mapping can be properly applied. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317287 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
87cdca2231
commit
d8375d7368
@ -98,6 +98,18 @@ RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{
|
||||
// LastCrossRegCpyIdx.
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
// 41: FPExt: 16 to 32. <-- This must match FPExt16To32Idx.
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
|
||||
// 43: FPExt: 16 to 32. <-- This must match FPExt16To64Idx.
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
|
||||
// 45: FPExt: 32 to 64. <-- This must match FPExt32To64Idx.
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
// 47: FPExt vector: 64 to 128. <-- This must match FPExt64To128Idx.
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
};
|
||||
|
||||
bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx,
|
||||
@ -217,4 +229,35 @@ AArch64GenRegisterBankInfo::getCopyMapping(unsigned DstBankID,
|
||||
ValMappingIdx <= LastCrossRegCpyIdx && "Mapping out of bound");
|
||||
return &ValMappings[ValMappingIdx];
|
||||
}
|
||||
|
||||
const RegisterBankInfo::ValueMapping *
|
||||
AArch64GenRegisterBankInfo::getFPExtMapping(unsigned DstSize,
|
||||
unsigned SrcSize) {
|
||||
// We support:
|
||||
// - For Scalar:
|
||||
// - 16 to 32.
|
||||
// - 16 to 64.
|
||||
// - 32 to 64.
|
||||
// => FPR 16 to FPR 32|64
|
||||
// => FPR 32 to FPR 64
|
||||
// - For vectors:
|
||||
// - v4f16 to v4f32
|
||||
// - v2f32 to v2f64
|
||||
// => FPR 64 to FPR 128
|
||||
|
||||
// Check that we have been asked sensible sizes.
|
||||
if (SrcSize == 16) {
|
||||
assert((DstSize == 32 || DstSize == 64) && "Unexpected half extension");
|
||||
if (DstSize == 32)
|
||||
return &ValMappings[FPExt16To32Idx];
|
||||
return &ValMappings[FPExt16To64Idx];
|
||||
}
|
||||
|
||||
if (SrcSize == 32) {
|
||||
assert(DstSize == 64 && "Unexpected float extension");
|
||||
return &ValMappings[FPExt32To64Idx];
|
||||
}
|
||||
assert((SrcSize == 64 || DstSize == 128) && "Unexpected vector extension");
|
||||
return &ValMappings[FPExt64To128Idx];
|
||||
}
|
||||
} // End llvm namespace.
|
||||
|
@ -175,6 +175,30 @@ AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
|
||||
CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 64);
|
||||
CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 64);
|
||||
|
||||
#define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize) \
|
||||
do { \
|
||||
unsigned PartialMapDstIdx = PMI_FPR##DstSize - PMI_Min; \
|
||||
unsigned PartialMapSrcIdx = PMI_FPR##SrcSize - PMI_Min; \
|
||||
(void)PartialMapDstIdx; \
|
||||
(void)PartialMapSrcIdx; \
|
||||
const ValueMapping *Map = getFPExtMapping(DstSize, SrcSize); \
|
||||
(void)Map; \
|
||||
assert(Map[0].BreakDown == \
|
||||
&AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] && \
|
||||
Map[0].NumBreakDowns == 1 && "FPR" #DstSize \
|
||||
" Dst is incorrectly initialized"); \
|
||||
assert(Map[1].BreakDown == \
|
||||
&AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] && \
|
||||
Map[1].NumBreakDowns == 1 && "FPR" #SrcSize \
|
||||
" Src is incorrectly initialized"); \
|
||||
\
|
||||
} while (false)
|
||||
|
||||
CHECK_VALUEMAP_FPEXT(32, 16);
|
||||
CHECK_VALUEMAP_FPEXT(64, 16);
|
||||
CHECK_VALUEMAP_FPEXT(64, 32);
|
||||
CHECK_VALUEMAP_FPEXT(128, 64);
|
||||
|
||||
assert(verify(TRI) && "Invalid register bank information");
|
||||
}
|
||||
|
||||
@ -455,6 +479,14 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
case TargetOpcode::G_FMUL:
|
||||
case TargetOpcode::G_FDIV:
|
||||
return getSameKindOfOperandsMapping(MI);
|
||||
case TargetOpcode::G_FPEXT: {
|
||||
LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
|
||||
LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
|
||||
return getInstructionMapping(
|
||||
DefaultMappingID, /*Cost*/ 1,
|
||||
getFPExtMapping(DstTy.getSizeInBits(), SrcTy.getSizeInBits()),
|
||||
/*NumOperands*/ 2);
|
||||
}
|
||||
case TargetOpcode::COPY: {
|
||||
unsigned DstReg = MI.getOperand(0).getReg();
|
||||
unsigned SrcReg = MI.getOperand(1).getReg();
|
||||
|
@ -53,7 +53,11 @@ protected:
|
||||
DistanceBetweenRegBanks = 3,
|
||||
FirstCrossRegCpyIdx = 25,
|
||||
LastCrossRegCpyIdx = 39,
|
||||
DistanceBetweenCrossRegCpy = 2
|
||||
DistanceBetweenCrossRegCpy = 2,
|
||||
FPExt16To32Idx = 41,
|
||||
FPExt16To64Idx = 43,
|
||||
FPExt32To64Idx = 45,
|
||||
FPExt64To128Idx = 47,
|
||||
};
|
||||
|
||||
static bool checkPartialMap(unsigned Idx, unsigned ValStartIdx,
|
||||
@ -82,6 +86,15 @@ protected:
|
||||
static const RegisterBankInfo::ValueMapping *
|
||||
getCopyMapping(unsigned DstBankID, unsigned SrcBankID, unsigned Size);
|
||||
|
||||
/// Get the instruction mapping for G_FPEXT.
|
||||
///
|
||||
/// \pre (DstSize, SrcSize) pair is one of the following:
|
||||
/// (32, 16), (64, 16), (64, 32), (128, 64)
|
||||
///
|
||||
/// \return An InstructionMapping with statically allocated OperandsMapping.
|
||||
static const RegisterBankInfo::ValueMapping *
|
||||
getFPExtMapping(unsigned DstSize, unsigned SrcSize);
|
||||
|
||||
#define GET_TARGET_REGBANK_CLASS
|
||||
#include "AArch64GenRegisterBank.inc"
|
||||
};
|
||||
|
@ -92,6 +92,10 @@
|
||||
store double %vres, double* %addr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @fp16Ext32() { ret void }
|
||||
define void @fp16Ext64() { ret void }
|
||||
define void @fp32Ext64() { ret void }
|
||||
...
|
||||
|
||||
---
|
||||
@ -742,3 +746,103 @@ body: |
|
||||
RET_ReallyLR
|
||||
|
||||
...
|
||||
|
||||
---
|
||||
# Make sure we map FPEXT on FPR register bank.
|
||||
# CHECK-LABEL: name: fp16Ext32
|
||||
name: fp16Ext32
|
||||
alignment: 2
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
||||
# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
|
||||
# CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' }
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
# CHECK: %1:gpr(s32) = COPY %w0
|
||||
# CHECK-NEXT: %0:gpr(s16) = G_TRUNC %1
|
||||
# %0 has been mapped to GPR, we need to repair to match FPR.
|
||||
# CHECK-NEXT: %3:fpr(s16) = COPY %0
|
||||
# CHECK-NEXT: %2:fpr(s32) = G_FPEXT %3
|
||||
# CHECK-NEXT: %s0 = COPY %2
|
||||
# CHECK-NEXT: RET_ReallyLR
|
||||
|
||||
body: |
|
||||
bb.1:
|
||||
liveins: %w0
|
||||
|
||||
%1(s32) = COPY %w0
|
||||
%0(s16) = G_TRUNC %1(s32)
|
||||
%2(s32) = G_FPEXT %0(s16)
|
||||
%s0 = COPY %2(s32)
|
||||
RET_ReallyLR implicit %s0
|
||||
|
||||
...
|
||||
|
||||
---
|
||||
# Make sure we map FPEXT on FPR register bank.
|
||||
# CHECK-LABEL: name: fp16Ext64
|
||||
name: fp16Ext64
|
||||
alignment: 2
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
||||
# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
|
||||
# CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' }
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
# CHECK: %1:gpr(s32) = COPY %w0
|
||||
# CHECK-NEXT: %0:gpr(s16) = G_TRUNC %1
|
||||
# %0 has been mapped to GPR, we need to repair to match FPR.
|
||||
# CHECK-NEXT: %3:fpr(s16) = COPY %0
|
||||
# CHECK-NEXT: %2:fpr(s64) = G_FPEXT %3
|
||||
# CHECK-NEXT: %d0 = COPY %2
|
||||
# CHECK-NEXT: RET_ReallyLR
|
||||
|
||||
body: |
|
||||
bb.1:
|
||||
liveins: %w0
|
||||
|
||||
%1(s32) = COPY %w0
|
||||
%0(s16) = G_TRUNC %1(s32)
|
||||
%2(s64) = G_FPEXT %0(s16)
|
||||
%d0 = COPY %2(s64)
|
||||
RET_ReallyLR implicit %d0
|
||||
|
||||
...
|
||||
|
||||
---
|
||||
# Make sure we map FPEXT on FPR register bank.
|
||||
# CHECK-LABEL: name: fp32Ext64
|
||||
name: fp32Ext64
|
||||
alignment: 2
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
||||
# CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
||||
# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
# CHECK: %0:gpr(s32) = COPY %w0
|
||||
# %0 has been mapped to GPR, we need to repair to match FPR.
|
||||
# CHECK-NEXT: %2:fpr(s32) = COPY %0
|
||||
# CHECK-NEXT: %1:fpr(s64) = G_FPEXT %2
|
||||
# CHECK-NEXT: %d0 = COPY %1
|
||||
# CHECK-NEXT: RET_ReallyLR
|
||||
body: |
|
||||
bb.1:
|
||||
liveins: %w0
|
||||
|
||||
%0(s32) = COPY %w0
|
||||
%1(s64) = G_FPEXT %0(s32)
|
||||
%d0 = COPY %1(s64)
|
||||
RET_ReallyLR implicit %d0
|
||||
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user