Discussion of empty class parameter passing ABI led me to notice that r162402 broke sibcalls with arguments of size 0 in some cases. Before that commit, the code read

else if ((partial == 0 || args[i].pass_on_stack)
         && size != 0)
{
  rtx mem = validize_mem (args[i].value);

  /* Check for overlap with already clobbered argument area. */
  if (is_sibcall
      && mem_overlaps_already_clobbered_arg_p (XEXP (args[i].value, 0), size))
     *sibcall_failure = 1;

and after,

        else if (partial == 0 || args[i].pass_on_stack)
          {
            rtx mem = validize_mem (args[i].value);

            /* Check for overlap with already clobbered argument area,
               providing that this has non-zero size.  */
            if (is_sibcall
                && (size == 0
                    || mem_overlaps_already_clobbered_arg_p
                                         (XEXP (args[i].value, 0), size)))
              *sibcall_failure = 1;

So now we set *sibcall_failure if size==0, whereas before we didn't enter the outer block. The comment also contradicts the code.

OK for trunk?
commit 2fa659c5b7779ba190cd5e9d15a8b7bc3dc5df35
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Mar 16 12:57:37 2016 -0400

    	* calls.c (load_register_parameters): Fix zero size sibcall logic.

diff --git a/gcc/calls.c b/gcc/calls.c
index 7b28f43..6415e08 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2083,9 +2083,9 @@ load_register_parameters (struct arg_data *args, int num_actuals,
 	      /* Check for overlap with already clobbered argument area,
 	         providing that this has non-zero size.  */
 	      if (is_sibcall
-		  && (size == 0
-		      || mem_overlaps_already_clobbered_arg_p 
-					   (XEXP (args[i].value, 0), size)))
+		  && size != 0
+		  && (mem_overlaps_already_clobbered_arg_p
+		      (XEXP (args[i].value, 0), size)))
 		*sibcall_failure = 1;
 
 	      if (size % UNITS_PER_WORD == 0
diff --git a/gcc/testsuite/gcc.dg/sibcall-11.c b/gcc/testsuite/gcc.dg/sibcall-11.c
new file mode 100644
index 0000000..ae58770
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sibcall-11.c
@@ -0,0 +1,7 @@
+// Test for sibcall optimization with empty struct.
+// { dg-options "-O2" }
+// { dg-final { scan-assembler "jmp" { target i?86-*-* x86_64-*-* } } }
+
+struct A { };
+void f(struct A);
+void g(struct A a) { f(a); }

Reply via email to