This is an archive of the discontinued LLVM Phabricator instance.

AVX512F: FMA intrinsic + FNEG - sequence optimization
ClosedPublic

Authored by delena on Sep 4 2016, 12:28 PM.

Details

Summary

The previous patch https://reviews.llvm.org/D23313 does not cover AVX-512F, KNL set.
FNEG(x) operation is lowered to (bitcast (vpxor (bitcast x), (bitcast constfp(0x80000000))).
It happens because FP XOR is not supported for 512-bit data types on KNL and we use integer XOR instead.
I added pattern match for integer XOR.

Diff Detail

Repository
rL LLVM

Event Timeline

delena updated this revision to Diff 70291.Sep 4 2016, 12:28 PM
delena retitled this revision from to AVX512F: FMA intrinsic + FNEG - sequence optimization.
delena updated this object.
delena added reviewers: spatel, RKSimon, igorb.
delena set the repository for this revision to rL LLVM.
delena added a subscriber: llvm-commits.
spatel added inline comments.Sep 4 2016, 4:31 PM
../lib/Target/X86/X86ISelLowering.cpp
30304 ↗(On Diff #70291)

has -> have

30359–30361 ↗(On Diff #70291)

Can this be an assert?
assert(IsFNEGNode && "Expected FNEG node");

30385–30422 ↗(On Diff #70291)

This would be clearer/smaller if we switched just the opcode selection and sank the common 'getBitcast(getNode())' after the switch:

auto NewOpcode;
switch (Arg.getOpcode()) {
case X86ISD::FMADD: NewOpcode = X86ISD::FNMSUB; break;
case X86ISD::FMSUB: NewOpcode = X86ISD::FNMADD; break;
...
}
return DAG.getBitcast(OrigVT, DAG.getNode(NewOpcode, DL, VT, Arg.getNode()->ops());

If you do that refactoring on the original code as an NFC patch, I think it will make the diff on this part of this patch just one line of code.

delena updated this revision to Diff 70304.Sep 4 2016, 11:54 PM
delena marked an inline comment as done.

Some code style improvements after Sanjay's comments.

spatel added inline comments.Sep 5 2016, 2:21 PM
../lib/Target/X86/X86ISelLowering.cpp
30307 ↗(On Diff #70304)

This interface feels awkward. The normal pattern is:
static SDValue getFNeg(SDNode *N)

Ie, if there's no negated value, it will return the empty SDValue(), and the caller can use that as a bool value if it wants to.

30359–30361 ↗(On Diff #70304)

This question was missed?

delena added inline comments.Sep 6 2016, 2:56 AM
../lib/Target/X86/X86ISelLowering.cpp
30307 ↗(On Diff #70304)

Thanks! I was looking for a proper interface. You suggestion is better than all APIs that I tried till now.
I'll update the patch.

I still think that my first solution with late FNEG lowering was simpler. We handle too many different patterns for XOR/FXOR.

30359–30361 ↗(On Diff #70291)

It will fail on compilation in release mode:
bool IsFNEGNode = isFNEG(N, &Arg); - Unused variable IsFNEGNode
assert(IsFNEGNode && "Expected FNEG node");

delena updated this revision to Diff 70371.Sep 6 2016, 2:58 AM

Changed isFNEG() interface.

spatel accepted this revision.Sep 6 2016, 10:37 AM
spatel edited edge metadata.

LGTM - see inline comments for some nits.

../lib/Target/X86/X86ISelLowering.cpp
30303 ↗(On Diff #70371)

Fp -> FP

30307 ↗(On Diff #70371)

static?

30877 ↗(On Diff #70371)

formatting: SDValue &V

30878–30879 ↗(On Diff #70371)

combine to one line? if (SDValue Negval = isFNEG...)

This revision is now accepted and ready to land.Sep 6 2016, 10:37 AM
This revision was automatically updated to reflect the committed changes.