Re: [patch] Do not let validize_mem modify its argument

2016-10-17 Thread Richard Biener
On Sat, Oct 15, 2016 at 12:11 PM, Eric Botcazou  wrote:
> Hi,
>
> gcc.dg/atomic/c11-atomic-exec-1.c has been failing at -O2 -mcpu=v8 on SPARC
> since the fix for PR middle-end/61268 was installed, i.e. with all 5.x, 6.x
> and 7.0 compilers.  The failure mode is as follows:
>
> emit_cstore is called on:
>
> (mem/c:DF (plus:SI (plus:SI (reg/f:SI 104 virtual-stack-vars)
> (reg:SI 1753))
> (const_int 8 [0x8])) [2 D.1567+8 S8 A64])
>
> and does:
>
> last = get_last_insn ();
>
> then it calls prepare_operand, which calls copy_to_mode_reg, which calls
> emit_move_insn, which calls validize_mem, which modifies the MEM in-place:
>
> (mem/c:DF (plus:SI (reg/f:SI 1757)
> (const_int 8 [0x8])) [2 D.1567+8 S8 A64])
>
> after emitting an addition:
>
> (set (reg/f:SI 1757)
>  (plus:SI (reg/f:SI 104 virtual-stack-vars) (reg:SI 1753)))
>
> But the call to maybe_expand_insn from emit_cstore fails so:
>
>  delete_insns_since (last);
>
> is invoked and the addition is lost, i.e. (reg/f:SI 1757) will be emitted
> uninitialized in the RTL stream, leading to a SIGSEGV at run time.
>
> IMO this shows that the explow.c hunk of the fix for PR middle-end/61268 was
> ill-advised and should not have been accepted.  Having copy_to_mode_reg or
> emit_move_insn silently modify their argument is IMO a recipe for problems.

Agreed.

> So the attached patch backs it out nd I suggest installing on all branches.

Ok for trunk (and branches after a while).

Richard.

> Tested on x86_64-suse-linux.
>
>
> 2016-10-15  Eric Botcazou  
>
> * explow.c (validize_mem): Do not modify the argument in-place.
>
> --
> Eric Botcazou


[patch] Do not let validize_mem modify its argument

2016-10-15 Thread Eric Botcazou
Hi,

gcc.dg/atomic/c11-atomic-exec-1.c has been failing at -O2 -mcpu=v8 on SPARC 
since the fix for PR middle-end/61268 was installed, i.e. with all 5.x, 6.x 
and 7.0 compilers.  The failure mode is as follows:

emit_cstore is called on:

(mem/c:DF (plus:SI (plus:SI (reg/f:SI 104 virtual-stack-vars)
(reg:SI 1753))
(const_int 8 [0x8])) [2 D.1567+8 S8 A64])

and does:

last = get_last_insn ();

then it calls prepare_operand, which calls copy_to_mode_reg, which calls 
emit_move_insn, which calls validize_mem, which modifies the MEM in-place:

(mem/c:DF (plus:SI (reg/f:SI 1757)
(const_int 8 [0x8])) [2 D.1567+8 S8 A64])

after emitting an addition:

(set (reg/f:SI 1757)
 (plus:SI (reg/f:SI 104 virtual-stack-vars) (reg:SI 1753)))

But the call to maybe_expand_insn from emit_cstore fails so:

 delete_insns_since (last);

is invoked and the addition is lost, i.e. (reg/f:SI 1757) will be emitted
uninitialized in the RTL stream, leading to a SIGSEGV at run time.

IMO this shows that the explow.c hunk of the fix for PR middle-end/61268 was 
ill-advised and should not have been accepted.  Having copy_to_mode_reg or 
emit_move_insn silently modify their argument is IMO a recipe for problems.

So the attached patch backs it out and I suggest installing on all branches.

Tested on x86_64-suse-linux.


2016-10-15  Eric Botcazou  

* explow.c (validize_mem): Do not modify the argument in-place.

-- 
Eric BotcazouIndex: explow.c
===
--- explow.c	(revision 241147)
+++ explow.c	(working copy)
@@ -496,9 +496,8 @@ memory_address_addr_space (machine_mode
   return x;
 }
 
-/* If REF is a MEM with an invalid address, change it into a valid address.
-   Pass through anything else unchanged.  REF must be an unshared rtx and
-   the function may modify it in-place.  */
+/* Convert a mem ref into one with a valid memory address.
+   Pass through anything else unchanged.  */
 
 rtx
 validize_mem (rtx ref)
@@ -510,7 +509,8 @@ validize_mem (rtx ref)
    MEM_ADDR_SPACE (ref)))
 return ref;
 
-  return replace_equiv_address (ref, XEXP (ref, 0), true);
+  /* Don't alter REF itself, since that is probably a stack slot.  */
+  return replace_equiv_address (ref, XEXP (ref, 0));
 }
 
 /* If X is a memory reference to a member of an object block, try rewriting