This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: PR 20203: unrecognizable insn building binutils
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 25 Feb 2005 21:54:43 +1030
- Subject: [PATCH]: PR 20203: unrecognizable insn building binutils
The testcase in PR 20203 sees expand generating a memory address of the
form (plus (mem) (const_int)) which is obviously invalid on ppc. The
cause is the expand_expr call in get_memory_rtx, which uses EXPAND_SUM.
When fed with
<plus_expr 0x8000205798
type <pointer_type 0x800029b9c0
type <integer_type 0x80002074e0 unsigned char public unsigned QI
size <integer_cst 0x80001ff4b0 constant invariant 8>
unit size <integer_cst 0x80001ff4e0 constant invariant 1>
align 8 symtab 0 alias set -1 precision 8 min <integer_cst 0x80001ff5a0 0> max <integer_cst 0x80001ff5d0 255>
pointer_to_this <pointer_type 0x800029b9c0>>
unsigned SI
size <integer_cst 0x80001ff8a0 constant invariant 32>
unit size <integer_cst 0x80001ff3c0 constant invariant 4>
align 32 symtab 0 alias set -1>
arg 0 <component_ref 0x800020c140 type <pointer_type 0x800029b9c0>
arg 0 <indirect_ref 0x80002dd100 type <record_type 0x80002d59c0 bfd_section>
arg 0 <parm_decl 0x80002db000 s>>
arg 1 <field_decl 0x80002d5c30 contents type <pointer_type 0x800029b9c0>
unsigned SI file /src/tmp/mips_miscompile.i line 6 size <integer_cst 0x80001ff8a0 32> unit size <integer_cst 0x80001ff3c0 4>
align 32 offset_align 128
offset <integer_cst 0x80001ff3f0 constant invariant 0> bit offset <integer_cst 0x80001ff8a0 32> context <record_type 0x80002d59c0 bfd_section> arguments <integer_cst 0x80001ff3f0 0>>>
arg 1 <convert_expr 0x80002dd1c0 type <pointer_type 0x800029b9c0>
arg 0 <convert_expr 0x80002dd140 type <integer_type 0x80002078f0 unsigned int>
arg 0 <nop_expr 0x80002dd0c0 type <integer_type 0x8000207b60 long long int>
arg 0 <minus_expr 0x80002056c0 type <integer_type 0x8000207a90 long unsigned int>
arg 0 <component_ref 0x800020c0f0 type <integer_type 0x8000207a90 long unsigned int>
arg 0 <indirect_ref 0x80002dd040 type <record_type 0x80002d59c0 bfd_section>
arg 0 <parm_decl 0x80002db000 s>> arg 1 <field_decl 0x80002d5b60 size>>
arg 1 <integer_cst 0x80002dc180 constant invariant 16>>>>>>
the chain of convert_exprs and nop_expr result in the minus_expr being
emitted, and, since this expansion is done with EXPAND_SUM it goes via
simplify_gen_binary here:
/* Convert A - const to A + (-const). */
if (GET_CODE (op1) == CONST_INT)
{
op1 = negate_rtx (mode, op1);
return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
}
This particular path doesn't do anything special regarding the MEM, so
we emit invalid rtl. I'm not sure whether expand_expr has already gone
wrong at this point, ie. whether EXPAND_SUM should mean that no
instructions are emitted on this tree, but I guess not. The description
of EXPAND_SUM seems to preclude conversions. (If we were left with one
big rtl expression, then break_out_memory_refs called in memory_address
would put all the mems in pseudos.)
I suppose another possibility is that this tree shouldn't be generated
in the first place..
PR target/20203
* builtins.c (get_memory_rtx): Expand address exp using EXPAND_NORMAL.
Remove convert_memory_address call duplicating that in memory_address.
Bootstrap and regression tests powerpc-linux and powerpc64-linux in
progress.
Index: gcc/builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.426
diff -u -p -r1.426 builtins.c
--- gcc/builtins.c 24 Feb 2005 20:00:04 -0000 1.426
+++ gcc/builtins.c 25 Feb 2005 08:04:09 -0000
@@ -978,12 +978,8 @@ expand_builtin_prefetch (tree arglist)
static rtx
get_memory_rtx (tree exp)
{
- rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
- rtx mem;
-
- addr = convert_memory_address (Pmode, addr);
-
- mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
+ rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
+ rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
/* Get an expression we can use to find the attributes to assign to MEM.
If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
--
Alan Modra
IBM OzLabs - Linux Technology Centre