This is an archive of the discontinued LLVM Phabricator instance.

LegalizeDAG: Fix and improve FCOPYSIGN/FABS legalization
ClosedPublic

Authored by MatzeB on Jul 13 2015, 7:12 PM.

Details

Summary
  • Factor out code to query and modify the sign bit of a floatingpoint value as an integer. This also works if none of the targets integer types is big enough to hold all bits of the floatingpoint value.
  • Legalize FABS(x) as FCOPYSIGN(x, 0.0) if FCOPYSIGN is available, otherwise perform bit manipulation on the sign bit. The previous code used "x >u 0 ? x : -x" which is incorrect for x being -0.0! It also takes 34 instructions on ARM Cortex-M4. With this patch we only require 5: vldr d0, LCPI0_0 vmov r2, r3, d0 lsrs r2, r3, #31 bfi r1, r2, #31, #1 bx lr (This could be further improved if the compiler would recognize that r2, r3 is zero).
  • Only lower FCOPYSIGN(x, y) = sign(x) ? -FABS(x) : FABS(x) if FABS is available otherwise perform bit manipulation on the sign bit.
  • Perform the sign(x) test by masking out the sign bit and comparing with 0 rather than shifting the sign bit to the highest position and testing for "<s 0". For x86 copysignl (on 80bit values) this gets us: testl $32768, %eax rather than: shlq $48, %rax sets %al testb %al, %al

This fixes http://llvm.org/PR24091

Diff Detail

Repository
rL LLVM

Event Timeline

MatzeB updated this revision to Diff 29639.Jul 13 2015, 7:12 PM
MatzeB retitled this revision from to LegalizeDAG: Fix and improve FCOPYSIGN/FABS legalization.
MatzeB updated this object.
MatzeB added a reviewer: resistor.
MatzeB set the repository for this revision to rL LLVM.
MatzeB added a subscriber: llvm-commits.
hfinkel added inline comments.
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
1579 ↗(On Diff #29639)

floatingpoint -> floating-point

1593 ↗(On Diff #29639)

floatingpoint -> floating-point

1595 ↗(On Diff #29639)

floatingpoint -> floating-point

1630 ↗(On Diff #29639)

But the float might also be smaller than the integer, right? Why don't you do an i8 extending load to the legal integer type? I think that would be better.

1649 ↗(On Diff #29639)

floatingpoint -> floating-point

MatzeB updated this revision to Diff 32489.Aug 18 2015, 6:24 PM

Thanks for the review, I changed the code to only load the byte containing the sign bit with ExtLoad/TruncStore.

hfinkel accepted this revision.Nov 11 2015, 9:31 AM
hfinkel added a reviewer: hfinkel.

A couple comments below, otherwise, LGTM.

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
1638 ↗(On Diff #32489)

No { } needed here.

1666 ↗(On Diff #32489)

It looks like this FABS check and expansion can be moved before the call to getSignAsIntValue, and if so, please do that.

This revision is now accepted and ready to land.Nov 11 2015, 9:31 AM
This revision was automatically updated to reflect the committed changes.

Thanks for the review!

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
1666 ↗(On Diff #32489)

The replacement code uses the "SignBit" variable as well so I don't think this can be easily moved.