This is an archive of the discontinued LLVM Phabricator instance.

[PowerPC][GISel]select floating point constant from TOC
ClosedPublic

Authored by shchenz on Sep 6 2022, 12:29 AM.

Details

Reviewers
Kai
nemanjai
amyk
arsenm
Group Reviewers
Restricted Project
Commits
rG6ee2f770efb6: [PowerPC][GISel] add support for fpconstant
Summary

Handle G_FCONSTANT node for PowerPC target.

Diff Detail

Event Timeline

shchenz created this revision.Sep 6 2022, 12:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 6 2022, 12:29 AM
shchenz requested review of this revision.Sep 6 2022, 12:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 6 2022, 12:29 AM

If I'm reading this correctly, the DAG handles this by letting the ConstantFP lower to a generic load with a constant pool PseudoSourceValue. I think that would be a better approach, rather than directly selecting G_FCONSTANT. You would avoid needing special 64-bit and 32-bit handling

llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
376

Return false to fallback is probably a better idea

418

Don't need &*

446

Ditto

shchenz marked 3 inline comments as done.Nov 29 2022, 11:22 PM

If I'm reading this correctly, the DAG handles this by letting the ConstantFP lower to a generic load with a constant pool PseudoSourceValue. I think that would be a better approach, rather than directly selecting G_FCONSTANT. You would avoid needing special 64-bit and 32-bit handling

Make sense. I updated the patch to generate a generic load while selecting ConstantFP, so that we can handle the load type inside the selection for G_LOAD. We still have to directly select the address for global variables, DAG handles this in both PPCISelDAGTODAG.cpp and td file.

One improvement implemented in DAG and directly selecting, but missing in the new method, we can further improve our code generation for medium code model in further patch:

addi 3, 3, .LCPI0_0@toc@l
lfs 1, 0(3)

->

lfs 1, .LCPI0_0@toc@l(3)
shchenz updated this revision to Diff 478815.Nov 29 2022, 11:24 PM

use generic load node

shchenz added inline comments.Nov 29 2022, 11:29 PM
llvm/test/CodeGen/PowerPC/GlobalISel/fconstant.ll
21

This can be improved to lfs 1, .LCPI0_0@toc@l(3). DAG adds a peephole to handle this.

shchenz updated this revision to Diff 479123.Nov 30 2022, 5:32 PM

remove the assertion

arsenm requested changes to this revision.Dec 6 2022, 12:31 PM
arsenm added inline comments.
llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
229–233

This should have been done in the legalizer, not the selector

This revision now requires changes to proceed.Dec 6 2022, 12:31 PM
shchenz added inline comments.Dec 7 2022, 5:02 PM
llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
229–233

I am not quite sure I understand your suggestion here. Do you mean we set action for G_FCONSTANT as custom for S32 and S64 in PPCLegalizerInfo? For my understanding, legalizer should do legalization for the types that are illegal for some opcodes on a certain target, right? float and double are both valid types on PPC. So not sure why we need to legalize them or do I misunderstand your comment? Thank you!

amyk added inline comments.Dec 8 2022, 7:08 AM
llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
187

Minor wording suggestion.

189

Minor wording suggestion.

205

Since the large and medium code models looks like they differ from just the opcode, does it make sense to do something like this?

unsigned Opcode = 0;
if (CModel == CodeModel::Large)
  // For large code model, generate LDtocL(CPI, ADDIStocHA8(X2, CPI))
  Opcode = PPC::LDtocL;
else
  // For medium code model, generate ADDItocL(CPI, ADDIStocHA8(X2, CPI))
  Opcode = PPC::ADDItocL;

Register HaAddrReg =
        MRI.createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
BuildMI(*I.getParent(), I, DbgLoc, TII.get(PPC::ADDIStocHA8), HaAddrReg)
        .addReg(PPC::X2)
        .addConstantPoolIndex(CPI);

BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opcode), AddrReg)
          .addConstantPoolIndex(CPI)
          .addReg(HaAddrReg);
arsenm added inline comments.Dec 8 2022, 7:19 AM
llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
229–233

Essentially yes, but not quite like that. I think the default lower action for G_CONSTANT/G_FCONSTANT should look like what the DAG does, which produces a constant pool load. You will need to introduce a new generic G_CONSTANT_POOL instruction.

So you would set your action to lower and implement this in the generic LegalizerHelper. Even if float and double are "legal types", the fact that you are replacing these with load indicates constants are not legal.

shchenz updated this revision to Diff 482037.Dec 12 2022, 1:58 AM
shchenz marked 2 inline comments as done.

address comments from @arsenm and @amyk

llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
205

Thanks, the operands order for PPC::LDtocL and PPC::ADDItocL is different and the operands number are also different. Indirect access PPC::LDtocL would have a memory operand.

shchenz marked an inline comment as done.Dec 12 2022, 1:59 AM
arsenm requested changes to this revision.Dec 12 2022, 4:59 PM

Can you also add a test in test/MachineVerifier/test_g_constant_pool.mir with the constraints of the instruction

llvm/docs/GlobalISel/GenericOpcode.rst
72 ↗(On Diff #482037)

Just G_CONSTANT_POOL?

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
2639 ↗(On Diff #482037)

This certainly isn't the alloca addrspace. getDefaultGlobalsAddressSpace maybe?

This revision now requires changes to proceed.Dec 12 2022, 4:59 PM
shchenz updated this revision to Diff 482691.Dec 13 2022, 7:29 PM

address @arsenm comments

Thanks for review @arsenm , updated accordingly.

llvm/docs/GlobalISel/GenericOpcode.rst
72 ↗(On Diff #482037)

I use G_CONSTANT_POOL_INDEX instead of G_CONSTANT_POOL is because of the name used in lib/CodeGen/GlobalISel/MachineIRBuilder.cpp. According to the name convention there, MachineIRBuilder::buildConstantPool() is a little confused to me. If you insist, I can change this to G_CONSTANT_POOL.

arsenm added inline comments.Dec 20 2022, 7:04 PM
llvm/docs/GlobalISel/GenericOpcode.rst
72 ↗(On Diff #482037)

I don't follow what you mean about the convention. The index is just what the source happens to be. This returns a constant pool. It's also called ConstantPool in the dag, so this should be G_CONSTANT_POOL

shchenz updated this revision to Diff 484454.Dec 20 2022, 7:49 PM

rebase and rename G_CONSTANT_POOL_INDEX

arsenm accepted this revision.Jan 4 2023, 7:24 AM

LGTM, thanks. Some test nits

llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll
2

This doesn't require asserts

4

I prefer -global-isel as the first llc argument

7

Drop -verify-machineinstrs, you only want the legalization error anyway

13

Don't hardcode the register number

This revision is now accepted and ready to land.Jan 4 2023, 7:24 AM
nemanjai added inline comments.Jan 4 2023, 1:09 PM
llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
396

Is this really the alignment we want? Seems like we should use whatever the ABI alignment is for the type.

404

I understand that this is always PPC::X2 for ELFv2, but can we use getTOCPointerRegister() instead?

llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
52

In SDAG, we have the capability to mark specific FP constants legal. Does a similar capability exist with GISel? Not using constant pool loads for constants such as 0.0 is quite important.
Perhaps a TODO is in order here?

llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll
2

Hmm, is it that producing FP constants using GISel is not supported or that GISel is not supported at all for BE and 32-bit? I imagine it is the latter.

arsenm added inline comments.Jan 4 2023, 1:11 PM
llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
52

It's not implemented. You could custom lower it, or use the immediate legal hook in the default lower implementation

shchenz updated this revision to Diff 486475.Jan 4 2023, 11:30 PM
shchenz marked 7 inline comments as done.

address comments from @arsenm and @nemanjai

llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
52

Yes, GISel has the ability to mark specific FP constants legal/custom/lower at same opcode in the legalizerinfo classs.

llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll
2

Yes, GISel is not supported at all for BE for now. GISel supports 32 bit, but PPC does not support 32 bit GISel for now.

nemanjai added inline comments.Jan 5 2023, 7:21 AM
llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll
2

Right. But I would expect that we simply reject an attempt to use GISel for ppc32 rather than trying to turn it on and possibly selecting an incorrect instruction. Namely, treat it the same as big endian targets are treated.

shchenz marked an inline comment as done.Jan 5 2023, 7:49 PM
shchenz added inline comments.
llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll
2

OK. Got your point. At the beginning of GISel, IRTranslator pass, the big endian case triggers an error.
For ppc32, maybe a virtual function isGlobalISelEnabled() is needed in class LLVMTargetMachine and an override version is needed in class PPCTargetMachine and only isELFv2ABI() returns true for now in the PPC's implementation? If so, I can add another patch to do this.

amyk added inline comments.Jan 19 2023, 12:41 PM
llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
376

nit: constant pool

413

nit: We can omit the { } since we have one assignment inside.

llvm/test/MachineVerifier/test_g_constant_pool.mir
1 ↗(On Diff #486475)

Nit: Spacing before RUN and this line may be too long.

2 ↗(On Diff #486475)

A question I had was, do we need a PPC version of this test?

arsenm added inline comments.Jan 19 2023, 2:15 PM
llvm/test/MachineVerifier/test_g_constant_pool.mir
2 ↗(On Diff #486475)

No, this could be any target . This one is simple enough that it might be able to get away with the default target

shchenz updated this revision to Diff 496820.Feb 12 2023, 6:44 PM
shchenz marked 4 inline comments as done.

address comments from @amyk

arsenm accepted this revision.Feb 13 2023, 5:00 PM
This revision was landed with ongoing or failed builds.Feb 13 2023, 6:39 PM
This revision was automatically updated to reflect the committed changes.