[llvm] [AArch64][GISel] Assign registers into FPR if they feed into FP instructions indirectly via PHI (PR #94618)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 6 08:25:08 PDT 2024


Him188 wrote:

> True and why? If the def of the G_PHI is used by fp-ops then why the copy?

Check the legalized MIR:
```
%1:_(s32) = G_LOAD %2(p0) :: (dereferenceable load (s32) from @aa, align 64, !tbaa !0)

%4:_(s32) = G_PHI %1(s32), %bb.1, %11(s32), %bb.2

%26:_(s32) = G_FCMP floatpred(ogt), %9(s32), %4
%11:_(s32) = G_SELECT %26(s32), %9, %4
```

When assigning regbank for G_LOAD, RBS iterates through all usages (see below). In our case it will find `%1` being used only by G_PHI. 
G_PHI neither `onlyUsesFP` nor `onlyDefinesFP`. So `%1` is assigned the default GPR.

Then %4 will be in GPR, and we need a COPY from GPR to FPR before G_FCMP. 


```c++
AArch64RegisterBankInfo::getInstrMapping() {
  ...
  case TargetOpcode::G_LOAD: {
    ...

    // Check if that load feeds fp instructions.
    // In that case, we want the default mapping to be on FPR
    // instead of blind map every scalar to GPR.
    if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
               [&](const MachineInstr &UseMI) {
                 // 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.
                 //
                 // Int->FP conversion operations are also captured in
                 // onlyDefinesFP().
                 return onlyUsesFP(UseMI, MRI, TRI) ||
                        onlyDefinesFP(UseMI, MRI, TRI);
               }))
      OpRegBankIdx[0] = PMI_FirstFPR;
    break;
```

https://github.com/llvm/llvm-project/pull/94618


More information about the llvm-commits mailing list