This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, rev2], Fix PR target/pr83862: Fix PowerPC long double signbit with -mabi=ieeelongdouble


I've reworked the patch for PR83864.  This bug is due to the compiler issuing
an internal error for code of the form on a little endian system:

    int sb (_Float128 *p, unsigned long n) { return __builtin_signbit (p[n]); }

The problem is that the memory optimization wants to load the high double word
from memory to isolate the signbit.  In little endian, the high word is at
offset 8 instead of 0.

The bug will also show up if you use the long double type, and you use the
-mabi=ieeelongdouble option.

Previously the code did one UNSPEC (signbit<mode>2_dm) that was done before
register allocation, and combined the value being in vector register, memory,
and GPR register along with the shift to isolate the signbit.  Then after the
split after register allocation, it created a second UNSPEC
(signbit<mode>2_dm2) that was just the direct move, or it did the memory and
GPR code path separately.

With these patches, the generator code issues an UNSPEC (signbit<mode>2_dm)
just to get the high double word, and the shift right is then emitted.  The
UNSPEC only handles the value being in either vector or GPR register.  There is
a second UNSPEC that is created by the combiner if the value is in memory.  On
little endian systems, the first split pass (before register allocation) will
allocate a pseudo register to hold the initial ADD of the base and index
registers for indexed loads, and then forms a LD reg,8(tmp) to load the high
word.  Just in case, some code after register allocation reforms the UNSPEC, it
uses a base register for the load, and it can use the base register as needed
for the temporary.

I have run this code on both little endian and big endian power8 systems, doing
bootstrap and regression test.  There were no regressions.  Can I install this
bug on the trunk?

I don't believe the bug shows up in gcc 6/7 branches, but I will build these
and test to see if the code is needed to be backported.

[gcc]
2018-01-21  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/83862
	* config/rs6000/rs6000-protos.h (rs6000_split_signbit): Delete,
	no longer used.
	* config/rs6000/rs6000.c (rs6000_split_signbit): Likewise.
	* config/rs6000/rs6000.md (signbit<mode>2): Change code for IEEE
	128-bit to produce an UNSPEC move to get the double word with the
	signbit and then a shift directly to do signbit.
	(signbit<mode>2_dm): Replace old IEEE 128-bit signbit
	implementation with a new version that just does either a direct
	move or a regular move.  Move memory interface to separate insns.
	Move insns so they are next to the expander.
	(signbit<mode>2_dm_mem_be): New combiner insns to combine load
	with signbit move.  Split big and little endian case.
	(signbit<mode>2_dm_mem_le): Likewise.
	(signbit<mode>2_dm_<su>ext): Delete, no longer used.
	(signbit<mode>2_dm2): Likewise.

[gcc/testsuite]
2018-01-22  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/83862
	* gcc.target/powerpc/pr83862.c: New test.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797

Attachment: pr83862.patch04b
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]