re PR rtl-optimization/91347 (hppa: wrong code generated with tail call optimisation)
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 20 Aug 2019 09:10:53 +0000 (09:10 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 20 Aug 2019 09:10:53 +0000 (09:10 +0000)
PR rtl-optimization/91347
* dse.c (scan_insn): Call add_wild_read for non-const/memset tail calls
before reload if HARD_FRAME_POINTER_IS_ARG_POINTER.

From-SVN: r274708

gcc/ChangeLog
gcc/dse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20190820-1.c [new file with mode: 0644]

index dd9838f2678b9fc061ae35123f6cfd4a8b612441..7130cdab526dde9584a2907f6c38aa0dc35d321a 100644 (file)
@@ -1,3 +1,9 @@
+2019-08-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR rtl-optimization/91347
+       * dse.c (scan_insn): Call add_wild_read for non-const/memset tail calls
+       before reload if HARD_FRAME_POINTER_IS_ARG_POINTER.
+
 2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>
 
        * calls.h (function_arg_info): Add a pass_by_reference field,
index 7511f71b9c0b1cdb8066e718bcd0fac780f027ea..5e270f9a5b477627a73e1f77e00fabbe3a315773 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2539,10 +2539,13 @@ scan_insn (bb_info_t bb_info, rtx_insn *insn)
                clear_rhs_from_active_local_stores ();
            }
        }
-      else if (SIBLING_CALL_P (insn) && reload_completed)
+      else if (SIBLING_CALL_P (insn)
+              && (reload_completed || HARD_FRAME_POINTER_IS_ARG_POINTER))
        /* Arguments for a sibling call that are pushed to memory are passed
           using the incoming argument pointer of the current function.  After
-          reload that might be (and likely is) frame pointer based.  */
+          reload that might be (and likely is) frame pointer based.  And, if
+          it is a frame pointer on the target, even before reload we need to
+          kill frame pointer based stores.  */
        add_wild_read (bb_info);
       else
        /* Every other call, including pure functions, may read any memory
index 9dee58caad35a7369d7b8cb3ede64dd10f48b0ec..e4cc820f0f71a163d837ba8409f88b89b3bac96e 100644 (file)
@@ -1,3 +1,7 @@
+2019-08-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.c-torture/execute/20190820-1.c: New test.
+
 2019-08-20  Richard Biener  <rguenther@suse.de>
 
        PR target/91498
diff --git a/gcc/testsuite/gcc.c-torture/execute/20190820-1.c b/gcc/testsuite/gcc.c-torture/execute/20190820-1.c
new file mode 100644 (file)
index 0000000..6a06eff
--- /dev/null
@@ -0,0 +1,111 @@
+/* PR rtl-optimization/91347 */\r
+/* Reported by John David Anglin <danglin@gcc.gnu.org> */\r
+\r
+typedef unsigned short __u16;\r
+typedef __signed__ int __s32;\r
+typedef unsigned int __u32;\r
+typedef __signed__ long long __s64;\r
+typedef unsigned long long __u64;\r
+typedef __u16 u16;\r
+typedef __s32 s32;\r
+typedef __u32 u32;\r
+typedef __u64 u64;\r
+typedef _Bool bool;\r
+typedef s32 int32_t;\r
+typedef u32 uint32_t;\r
+typedef u64 uint64_t;\r
+\r
+char hex_asc_upper[16];\r
+u16 decpair[100];\r
+\r
+static __attribute__ ((noipa)) void\r
+put_dec_full4 (char *buf, unsigned r)\r
+{\r
+ unsigned q;\r
+ q = (r * 0x147b) >> 19;\r
+ *((u16 *)buf) = decpair[r - 100*q];\r
+ buf += 2;\r
+ *((u16 *)buf) = decpair[q];\r
+}\r
+\r
+static __attribute__ ((noipa)) unsigned\r
+put_dec_helper4 (char *buf, unsigned x)\r
+{\r
+  uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43;\r
+  put_dec_full4(buf, x - q * 10000);\r
+  return q;\r
+}\r
+\r
+static __attribute__ ((noipa)) char *\r
+put_dec (char *buf, unsigned long long n)\r
+{\r
+ uint32_t d3, d2, d1, q, h;\r
+ d1 = ((uint32_t)n >> 16);\r
+ h = (n >> 32);\r
+ d2 = (h ) & 0xffff;\r
+ d3 = (h >> 16);\r
+ q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff);\r
+ q = put_dec_helper4(buf, q);\r
+ q += 7671 * d3 + 9496 * d2 + 6 * d1;\r
+ q = put_dec_helper4(buf+4, q);\r
+ q += 4749 * d3 + 42 * d2;\r
+ q = put_dec_helper4(buf+8, q);\r
+ return buf;\r
+}\r
+\r
+struct printf_spec {\r
+ unsigned int type:8;\r
+ signed int field_width:24;\r
+ unsigned int flags:8;\r
+ unsigned int base:8;\r
+ signed int precision:16;\r
+} __attribute__((__packed__));\r
+\r
+static __attribute__ ((noipa)) char *\r
+number (char *buf, char *end, unsigned long long num, struct printf_spec spec)\r
+{\r
+\r
+ char tmp[3 * sizeof(num)] __attribute__((__aligned__(2)));\r
+ char sign;\r
+ char locase;\r
+ int need_pfx = ((spec.flags & 64) && spec.base != 10);\r
+ int i;\r
+ bool is_zero = num == 0LL;\r
+ int field_width = spec.field_width;\r
+ int precision = spec.precision;\r
+\r
+ i = 0;\r
+ if (num < spec.base)\r
+  tmp[i++] = hex_asc_upper[num] | locase;\r
+ else if (spec.base != 10) {\r
+  int mask = spec.base - 1;\r
+  int shift = 3;\r
+  if (spec.base == 16)\r
+   shift = 4;\r
+  else\r
+    __builtin_abort ();\r
+  do {\r
+   tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] | locase);\r
+   num >>= shift;\r
+  } while (num);\r
+ } else {\r
+  i = put_dec(tmp, num) - tmp;\r
+ }\r
+ return buf;\r
+}\r
+\r
+static __attribute__ ((noipa)) char *\r
+pointer_string (char *buf, char *end, const void *ptr, struct printf_spec spec)\r
+{\r
+ spec.base = 16;\r
+ spec.flags = 0;\r
+ return number(buf, end, 100, spec);\r
+}\r
+\r
+int\r
+main (void)\r
+{\r
+  struct printf_spec spec;\r
+  char *s = pointer_string (0, 0, 0, spec);\r
+  return 0;\r
+}\r