[AArch64] Map G_STORE on FPR when the source comes from a FPR copy
authorQuentin Colombet <qcolombet@apple.com>
Sat, 18 Nov 2017 04:28:58 +0000 (04:28 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Sat, 18 Nov 2017 04:28:58 +0000 (04:28 +0000)
We used to detect that stores were fed by fp instructions, but we were
failing to take into account cases where this happens through copies.
For instance, stores can be fed by copies coming from the ABI lowering
of floating point arguments.

llvm-svn: 318588

llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir

index 5289063..9940a74 100644 (file)
@@ -611,7 +611,15 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
       if (!VReg)
         break;
       MachineInstr *DefMI = MRI.getVRegDef(VReg);
-      if (isPreISelGenericFloatingPointOpcode(DefMI->getOpcode()))
+      unsigned DefOpc = DefMI->getOpcode();
+      if (isPreISelGenericFloatingPointOpcode(DefOpc) ||
+          // Check if we come from a copy-like instruction with
+          // floating point constraints. In that case, we are still
+          // fed by fp instructions, but indirectly
+          // (e.g., through ABI copies).
+          ((DefOpc == TargetOpcode::COPY || DefMI->isPHI()) &&
+           getRegBank(DefMI->getOperand(0).getReg(), MRI, TRI) ==
+               &AArch64::FPRRegBank))
         OpRegBankIdx[0] = PMI_FirstFPR;
       break;
     }
index a5df93b..aace553 100644 (file)
@@ -911,26 +911,20 @@ body:             |
 
 ...
 ---
-# This test tries to mix 16-bit types on fpr with 32-bit types on gpr.
-# The problem when doing that is that switching from fpr to gpr requires
-# more than just a plain COPY.
-# In this specific case, currently we map the ABI copy from h0 to fpr,
-# then, the fast mapping takes GPR for store and the size of the storage
-# gets bumped to 32-bit.
+# Make sure we properly detect fp types through copies.
+# In that example, the copy comes from an ABI lowering of a fp type.
 # CHECK-LABEL: name: passFp16ViaAllocas
 # 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: 3, class: gpr, preferred-register: '' }
 #
 # CHECK:  %0:fpr(s16) = COPY %h0
 # CHECK-NEXT: %1:gpr(p0) = G_FRAME_INDEX %stack.0.p.addr
-# Currently the default mapping we provide for store does not
-# consider fpr for s16, unless they are produced by floating point
-# operation. Thus, we have to repair the assignment.
-# CHECK-NEXT: %3:gpr(s16) = COPY %0(s16)
-# CHECK-NEXT: G_STORE %3(s16), %1(p0) :: (store 2 into %ir.p.addr)
+# If we didn't look through the copy for %0, the default mapping
+# 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)
 # CHECK-NEXT: %h0 = COPY %2(s16)
 name:            passFp16ViaAllocas