diff options
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp | 13 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir | 7 |
2 files changed, 16 insertions, 4 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index 9940a74d7a8..c497669f937 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -594,15 +594,24 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { // In that case, we want the default mapping to be on FPR // instead of blind map every scalar to GPR. for (const MachineInstr &UseMI : - MRI.use_instructions(MI.getOperand(0).getReg())) + MRI.use_instructions(MI.getOperand(0).getReg())) { // If we have at least one direct use in a FP instruction, // assume this was a floating point load in the IR. // If it was not, we would have had a bitcast before // reaching that instruction. - if (isPreISelGenericFloatingPointOpcode(UseMI.getOpcode())) { + unsigned UseOpc = UseMI.getOpcode(); + if (isPreISelGenericFloatingPointOpcode(UseOpc) || + // Check if we feed a copy-like instruction with + // floating point constraints. In that case, we are still + // feeding fp instructions, but indirectly + // (e.g., through ABI copies). + ((UseOpc == TargetOpcode::COPY || UseMI.isPHI()) && + getRegBank(UseMI.getOperand(0).getReg(), MRI, TRI) == + &AArch64::FPRRegBank)) { OpRegBankIdx[0] = PMI_FirstFPR; break; } + } break; case TargetOpcode::G_STORE: // Check if that store is fed by fp instructions. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir index aace553af2d..a27cf2bea78 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir @@ -917,7 +917,7 @@ body: | # CHECK: registers: # CHECK: - { id: 0, class: fpr, preferred-register: '' } # CHECK: - { id: 1, class: gpr, preferred-register: '' } -# CHECK: - { id: 2, class: gpr, preferred-register: '' } +# CHECK: - { id: 2, class: fpr, preferred-register: '' } # # CHECK: %0:fpr(s16) = COPY %h0 # CHECK-NEXT: %1:gpr(p0) = G_FRAME_INDEX %stack.0.p.addr @@ -925,7 +925,10 @@ body: | # would have been on GPR and we would have to insert a copy to move # the value away from FPR (h0). # CHECK-NEXT: G_STORE %0(s16), %1(p0) :: (store 2 into %ir.p.addr) -# CHECK-NEXT: %2:gpr(s16) = G_LOAD %1(p0) :: (load 2 from %ir.p.addr) +# If we didn't look through the copy for %2, the default mapping +# would have been on GPR and we would have to insert a copy to move +# the value to FPR (h0). +# CHECK-NEXT: %2:fpr(s16) = G_LOAD %1(p0) :: (load 2 from %ir.p.addr) # CHECK-NEXT: %h0 = COPY %2(s16) name: passFp16ViaAllocas alignment: 2 |