* config/i386/i386.md (sibcall_memory): Check that register with
authoramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 14 May 2015 17:43:28 +0000 (17:43 +0000)
committeramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 14 May 2015 17:43:28 +0000 (17:43 +0000)
callee address is not also used as one of the arguments, instead
of checking that it is not live after the sibcall.
(sibcall_pop_memory): Ditto.
(sibcall_value_memory): Ditto.
(sibcall_value_pop_memory): Ditto.
testsuite:
* gcc.target/i386/sibcall-7.c: New test.
* gcc.target/i386/sibcall-8.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@223201 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/sibcall-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sibcall-8.c [new file with mode: 0644]

index f41771e..97aa0eb 100644 (file)
@@ -1,3 +1,12 @@
+2015-05-14  Alexander Monakov  <amonakov@ispras.ru>
+
+       * config/i386/i386.md (sibcall_memory): Check that register with
+       callee address is not also used as one of the arguments, instead
+       of checking that it is not live after the sibcall.
+       (sibcall_pop_memory): Ditto.
+       (sibcall_value_memory): Ditto.
+       (sibcall_value_pop_memory): Ditto. 
+
 2015-05-14  Marc Glisse  <marc.glisse@inria.fr>
 
        * generic-match-head.c (types_match): Handle non-types.
index 7bec509..aefca43 100644 (file)
    (call (mem:QI (match_dup 0))
         (match_operand 3))]
   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
-   && peep2_reg_dead_p (2, operands[0])"
+   && !reg_mentioned_p (operands[0],
+                       CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
   [(parallel [(call (mem:QI (match_dup 1))
                    (match_dup 3))
              (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
    (call (mem:QI (match_dup 0))
         (match_operand 3))]
   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
-   && peep2_reg_dead_p (3, operands[0])"
+   && !reg_mentioned_p (operands[0],
+                       CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
    (parallel [(call (mem:QI (match_dup 1))
                    (match_dup 3))
                   (plus:SI (reg:SI SP_REG)
                            (match_operand:SI 4 "immediate_operand")))])]
   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
-   && peep2_reg_dead_p (2, operands[0])"
+   && !reg_mentioned_p (operands[0],
+                       CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
   [(parallel [(call (mem:QI (match_dup 1))
                    (match_dup 3))
              (set (reg:SI SP_REG)
                   (plus:SI (reg:SI SP_REG)
                            (match_operand:SI 4 "immediate_operand")))])]
   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
-   && peep2_reg_dead_p (3, operands[0])"
+   && !reg_mentioned_p (operands[0],
+                       CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
    (parallel [(call (mem:QI (match_dup 1))
                    (match_dup 3))
    (call (mem:QI (match_dup 0))
                 (match_operand 3)))]
   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
-   && peep2_reg_dead_p (2, operands[0])"
+   && !reg_mentioned_p (operands[0],
+                       CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
   [(parallel [(set (match_dup 2)
                   (call (mem:QI (match_dup 1))
                         (match_dup 3)))
        (call (mem:QI (match_dup 0))
              (match_operand 3)))]
   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
-   && peep2_reg_dead_p (3, operands[0])"
+   && !reg_mentioned_p (operands[0],
+                       CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
    (parallel [(set (match_dup 2)
                   (call (mem:QI (match_dup 1))
                   (plus:SI (reg:SI SP_REG)
                            (match_operand:SI 4 "immediate_operand")))])]
   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
-   && peep2_reg_dead_p (2, operands[0])"
+   && !reg_mentioned_p (operands[0],
+                       CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
   [(parallel [(set (match_dup 2)
                   (call (mem:QI (match_dup 1))
                         (match_dup 3)))
                   (plus:SI (reg:SI SP_REG)
                            (match_operand:SI 4 "immediate_operand")))])]
   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
-   && peep2_reg_dead_p (3, operands[0])"
+   && !reg_mentioned_p (operands[0],
+                       CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
    (parallel [(set (match_dup 2)
                   (call (mem:QI (match_dup 1))
index 504dc07..2d48683 100644 (file)
@@ -1,3 +1,8 @@
+2015-05-14  Alexander Monakov  <amonakov@ispras.ru>
+
+       * gcc.target/i386/sibcall-7.c: New test.
+       * gcc.target/i386/sibcall-8.c: New test.
+
 2015-05-14  Wilco Dijkstra  <wdijkstr@arm.com>
 
        * gcc.target/aarch64/abs_1.c (abs64): Update test for new abs expansion.
        PR tree-optimization/37021
        * gcc.target/i386/vect-addsub.c: New testcase.
 
-2015-05-11  Alexander Monakov  <amonakov@ispras.ru>
+2015-05-12  Alexander Monakov  <amonakov@ispras.ru>
 
        * gcc.target/i386/pr65753.c: Use -O2 instead of -O.
 
diff --git a/gcc/testsuite/gcc.target/i386/sibcall-7.c b/gcc/testsuite/gcc.target/i386/sibcall-7.c
new file mode 100644 (file)
index 0000000..6effb8f
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "mov" } } */
+
+int foo()
+{
+  int (**bar)(void);
+  asm("":"=a"(bar));
+  return (*bar)();
+}
diff --git a/gcc/testsuite/gcc.target/i386/sibcall-8.c b/gcc/testsuite/gcc.target/i386/sibcall-8.c
new file mode 100644 (file)
index 0000000..3ab3809
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+static int __attribute__((regparm(1)))
+bar(void *arg)
+{
+  return arg != bar;
+}
+
+static int __attribute__((noinline,noclone,regparm(1)))
+foo(int (__attribute__((regparm(1))) **bar)(void*))
+{
+  return (*bar)(*bar);
+}
+
+int main()
+{
+  int (__attribute__((regparm(1))) *p)(void*) = bar;
+  if (foo(&p))
+    abort();
+  return 0;
+}