This is an archive of the discontinued LLVM Phabricator instance.

[X86] Adding fp128 support for strict fcmp
ClosedPublic

Authored by pengfei on Dec 26 2019, 6:20 AM.

Diff Detail

Event Timeline

pengfei created this revision.Dec 26 2019, 6:20 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 26 2019, 6:20 AM
craig.topper added inline comments.Dec 26 2019, 8:32 AM
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
299

How are you handling the fact that the available libcalls don’t cover all the signaling behaviors? You don’t seem to be using the IsSignalling parameter?

There are libcalls for OGT/OLT/OLE/OGE that are always signalling. There is a libcall for OEQ/UNE that not signalling. And there's a libcall for Ordered/Unordered that is not signalling.

Note, that despite having multiple names there are really only 3 total libcalls. The names are aliases and the return value is used to check direction. The OGT/OLT/OLE/OGE libcall returns -1, 0, or 1. The other oeq/une and the ordered/unordered just return true or false.

We may need to expand the unsupported calls into multiple compares and control flow in IR. For example for non-signalling ogt/olt/ole/oge we'll need to check unordered first and branch accordingly for qnans without calling the signalling ogt/olt/ole/oge libcall which will signal. Technically we could use a select to change the value we pass to the ogt/olt/ole/oge when its signalling, but select has to be expanded into control flow on many targets anyway. @uweigand, what are you thoughts on this?

pengfei marked an inline comment as done.Dec 26 2019, 5:51 PM

There are libcalls for OGT/OLT/OLE/OGE that are always signalling. There is a libcall for OEQ/UNE that not signalling. And there's a libcall for Ordered/Unordered that is not signalling.

Is the signaling/no signaling action by design (the API guarantees the behavior) or depended on targets. I don't find the description about signaling on GCC document. I guess it depends on targets.

Note, that despite having multiple names there are really only 3 total libcalls. The names are aliases and the return value is used to check direction. The OGT/OLT/OLE/OGE libcall returns -1, 0, or 1. The other oeq/une and the ordered/unordered just return true or false.

In fact, there're only two. one is used for OGT/OLT/OLE/OGE/OEQ/ONE, one for ORD/UOR.
Why didn't we expand form these two functions directly? I think it can reduce the code complicity. And it can improve performance by reducing potential calls.

We may need to expand the unsupported calls into multiple compares and control flow in IR. For example for non-signalling ogt/olt/ole/oge we'll need to check unordered first and branch accordingly for qnans without calling the signalling ogt/olt/ole/oge libcall which will signal. Technically we could use a select to change the value we pass to the ogt/olt/ole/oge when its signalling, but select has to be expanded into control flow on many targets anyway. @uweigand, what are you thoughts on this?

I think it can be simplified to directly use __unordXf2 and __cmpXf2, if we know it's a NaN from the former, we can call a new function TLI.raiseNaNException to handle exception respectively.

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
299

I realized I can't handle signaling, but forgot to delete it.

After a deeper investigation, I agreed with Craig that we should "expand the unsupported calls into multiple compares and control flow in IR". But I think we don't need libcalls. We can get sNaN, qNaN and compare results according to control flow and IRs. We only need to define a target dependent interface TLI.raiseFPException to handle exception respectively.

After a deeper investigation, I agreed with Craig that we should "expand the unsupported calls into multiple compares and control flow in IR". But I think we don't need libcalls. We can get sNaN, qNaN and compare results according to control flow and IRs. We only need to define a target dependent interface TLI.raiseFPException to handle exception respectively.

Having a raiseFPException code would make the exception generating code be inlined everywhere. And for X86 it requires generating an exception into both the SSE and X87 domain. That doesn't seem good for code size. We should push on the libraries to do the right thing.

RKSimon added inline comments.Jan 3 2020, 6:34 AM
llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
1131

nounwind to remove .cfi directives?

pengfei marked an inline comment as done.Jan 7 2020, 7:30 PM
llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
1131

Thanks!

pengfei updated this revision to Diff 236747.Jan 7 2020, 7:31 PM

Add Fixme for softenSetCCOperands. We don't want to add extra logic code instead of pushing the libraries to do the right thing.
Address review comment.

This revision is now accepted and ready to land.Jan 7 2020, 8:21 PM
This revision was automatically updated to reflect the committed changes.