This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
AIX c-torture failure from 2000-08-14 emit_group_load() change
- To: Richard Henderson <rth at redhat dot com>
- Subject: AIX c-torture failure from 2000-08-14 emit_group_load() change
- From: David Edelsohn <dje at watson dot ibm dot com>
- Date: Fri, 26 Jan 2001 00:01:12 -0500
- cc: gcc-bugs at gcc dot gnu dot org, Mark Mitchell <mark at codesourcery dot com>
The following change appears to be causing c-torture test
compile/960829-1.c to fail on AIX:
2000-08-14 Richard Henderson <rth@cygnus.com>
* expr.c (emit_group_load): Don't force constants into registers.
Special case source already in the correct mode.
The change in question is:
*** expr.c 2000/08/13 17:01:54 1.252
--- expr.c 2000/08/14 20:08:25 1.253
*************** emit_group_load (dst, orig_src, ssize, a
*** 1938,1944 ****
/* If we won't be loading directly from memory, protect the real
source
from strange tricks we might play. */
src = orig_src;
! if (GET_CODE (src) != MEM)
{
if (GET_MODE (src) == VOIDmode)
src = gen_reg_rtx (GET_MODE (dst));
--- 1938,1944 ----
/* If we won't be loading directly from memory, protect the real
source
from strange tricks we might play. */
src = orig_src;
! if (GET_CODE (src) != MEM && ! CONSTANT_P (src))
{
if (GET_MODE (src) == VOIDmode)
src = gen_reg_rtx (GET_MODE (dst));
*************** emit_group_load (dst, orig_src, ssize, a
*** 1987,1992 ****
--- 1987,1996 ----
else
abort ();
}
+ else if ((CONSTANT_P (src)
+ && (GET_MODE (src) == VOIDmode || GET_MODE (src) == mode))
+ || (GET_CODE (src) == REG && GET_MODE (src) == mode))
+ tmps[i] = src;
else
tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
bytepos * BITS_PER_UNIT, 1, NULL_RTX,
and the test now fails with:
960829-1.c: In function `f':
960829-1.c:3: Internal compiler error in change_address, at emit-rtl.c:1622
because change_address() is called with an argument of (const_int 0).
For testcase 960829-1.c, emit_group_load() is called with orig_src
of (const_double:DF (cc0) 0 [0x0] 0 [0x0] [0]) . The previous code would
move the value into a register, and the remainder of the function would
operate on the register. The patch keeps the value as a constant.
For the AIX PowerOpen ABI, the destination is an SImode register:
the function argument is passed in both the FPR and in two GPRs for
varargs to work. The special case in the latter half of the patch cannot
handle a CONST_DOUBLE:DF loaded into a register of a different mode and
the original fall-back method cannot handle the constant which no longer
is in a register.
I don't know if the solution should be for the first test to more
carefully match the second test of constants that it can handle or that
the latter case should be able to handle all constants which now fail the
first test.
David