diff mbox

CALL_INSN_FUNCTION_USAGE fix, PR52773

Message ID 51C1ECB7.5030804@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt June 19, 2013, 5:39 p.m. UTC
This is bug that triggers on m68k. The loop unroller creates a MULT
expression and tries to force it into a register, which causes a libcall
to be generated. Since args are pushed we create a
  (use (mem (plus virtual_outgoing_args scratch)))
in CALL_INSN_FUNCTION_USAGE. Since we're past vregs, the
virtual_outgoing_args rtx survives to reload, which blows up.

Fixed by just using stack_pointer_rtx, since we use a scratch anyway
rather than a known offset. I also noticed that we actually add two of
these USEs, so I've fixed that as well.

Bootstrapped and tested on x86_64-linux, ok?


Bernd

Comments

Andreas Schwab Feb. 10, 2014, 5:54 p.m. UTC | #1
Bernd Schmidt <bernds@codesourcery.com> writes:

> This is bug that triggers on m68k. The loop unroller creates a MULT
> expression and tries to force it into a register, which causes a libcall
> to be generated. Since args are pushed we create a
>   (use (mem (plus virtual_outgoing_args scratch)))
> in CALL_INSN_FUNCTION_USAGE. Since we're past vregs, the
> virtual_outgoing_args rtx survives to reload, which blows up.
>
> Fixed by just using stack_pointer_rtx, since we use a scratch anyway
> rather than a known offset. I also noticed that we actually add two of
> these USEs, so I've fixed that as well.
>
> Bootstrapped and tested on x86_64-linux, ok?

Any news on this?

Andreas.
Bernd Schmidt May 21, 2014, 9:37 a.m. UTC | #2
On 06/19/2013 07:39 PM, Bernd Schmidt wrote:
> This is bug that triggers on m68k. The loop unroller creates a MULT
> expression and tries to force it into a register, which causes a libcall
> to be generated. Since args are pushed we create a
>    (use (mem (plus virtual_outgoing_args scratch)))
> in CALL_INSN_FUNCTION_USAGE. Since we're past vregs, the
> virtual_outgoing_args rtx survives to reload, which blows up.
>
> Fixed by just using stack_pointer_rtx, since we use a scratch anyway
> rather than a known offset. I also noticed that we actually add two of
> these USEs, so I've fixed that as well.

Ping.

https://gcc.gnu.org/ml/gcc-patches/2013-06/msg01147.html


Bernd
Jeff Law May 21, 2014, 1:07 p.m. UTC | #3
On 05/21/14 03:37, Bernd Schmidt wrote:
> On 06/19/2013 07:39 PM, Bernd Schmidt wrote:
>> This is bug that triggers on m68k. The loop unroller creates a MULT
>> expression and tries to force it into a register, which causes a libcall
>> to be generated. Since args are pushed we create a
>>    (use (mem (plus virtual_outgoing_args scratch)))
>> in CALL_INSN_FUNCTION_USAGE. Since we're past vregs, the
>> virtual_outgoing_args rtx survives to reload, which blows up.
>>
>> Fixed by just using stack_pointer_rtx, since we use a scratch anyway
>> rather than a known offset. I also noticed that we actually add two of
>> these USEs, so I've fixed that as well.
>
> Ping.
>
> https://gcc.gnu.org/ml/gcc-patches/2013-06/msg01147.html
This is fine.  Thanks.

jeff
diff mbox

Patch

diff --git a/gcc/calls.c b/gcc/calls.c
index cdab8e0..db38b73 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3603,6 +3603,7 @@  emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
   int reg_parm_stack_space = 0;
   int needed;
   rtx before_call;
+  bool have_push_fusage;
   tree tfom;			/* type_for_mode (outmode, 0) */
 
 #ifdef REG_PARM_STACK_SPACE
@@ -3956,6 +3957,8 @@  emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
 
   /* Push the args that need to be pushed.  */
 
+  have_push_fusage = false;
+
   /* ARGNUM indexes the ARGVEC array in the order in which the arguments
      are to be pushed.  */
   for (count = 0; count < nargs; count++, argnum += inc)
@@ -4046,14 +4049,19 @@  emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
 	  if (argblock)
 	    use = plus_constant (Pmode, argblock,
 				 argvec[argnum].locate.offset.constant);
+	  else if (have_push_fusage)
+	    continue;
 	  else
-	    /* When arguments are pushed, trying to tell alias.c where
-	       exactly this argument is won't work, because the
-	       auto-increment causes confusion.  So we merely indicate
-	       that we access something with a known mode somewhere on
-	       the stack.  */
-	    use = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
-				gen_rtx_SCRATCH (Pmode));
+	    {
+	      /* When arguments are pushed, trying to tell alias.c where
+		 exactly this argument is won't work, because the
+		 auto-increment causes confusion.  So we merely indicate
+		 that we access something with a known mode somewhere on
+		 the stack.  */
+	      use = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+				  gen_rtx_SCRATCH (Pmode));
+	      have_push_fusage = true;
+	    }
 	  use = gen_rtx_MEM (argvec[argnum].mode, use);
 	  use = gen_rtx_USE (VOIDmode, use);
 	  call_fusage = gen_rtx_EXPR_LIST (VOIDmode, use, call_fusage);
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr52773.c b/gcc/testsuite/gcc.c-torture/compile/pr52773.c
new file mode 100644
index 0000000..8daa5ee
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr52773.c
@@ -0,0 +1,16 @@ 
+/* pr52773.c */
+
+struct s {
+    short x;
+    short _pad[2];
+};
+
+static short mat_a_x;
+
+void transform(const struct s *src, struct s *dst, int n)
+{
+    int i;
+
+    for (i = 0; i < n; ++i)
+	dst[i].x = (src[i].x * mat_a_x) >> 6;
+}