diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2019-08-20 09:10:53 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2019-08-20 09:10:53 +0000 |
commit | 7ee98586a66efe3219ef5a8b00bcced4b0da23e5 (patch) | |
tree | 99b6fb388126ba631bb521fc0e6c659b39eedb97 | |
parent | 257caa552bf930e2770100de70a459a4ede837c0 (diff) | |
download | gcc-7ee98586a66efe3219ef5a8b00bcced4b0da23e5.zip gcc-7ee98586a66efe3219ef5a8b00bcced4b0da23e5.tar.gz gcc-7ee98586a66efe3219ef5a8b00bcced4b0da23e5.tar.bz2 |
re PR rtl-optimization/91347 (hppa: wrong code generated with tail call optimisation)
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/dse.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20190820-1.c | 111 |
4 files changed, 126 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd9838f..7130cda 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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, @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9dee58c..e4cc820 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..6a06eff --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20190820-1.c @@ -0,0 +1,111 @@ +/* PR rtl-optimization/91347 */
+/* Reported by John David Anglin <danglin@gcc.gnu.org> */
+
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+typedef __u16 u16;
+typedef __s32 s32;
+typedef __u32 u32;
+typedef __u64 u64;
+typedef _Bool bool;
+typedef s32 int32_t;
+typedef u32 uint32_t;
+typedef u64 uint64_t;
+
+char hex_asc_upper[16];
+u16 decpair[100];
+
+static __attribute__ ((noipa)) void
+put_dec_full4 (char *buf, unsigned r)
+{
+ unsigned q;
+ q = (r * 0x147b) >> 19;
+ *((u16 *)buf) = decpair[r - 100*q];
+ buf += 2;
+ *((u16 *)buf) = decpair[q];
+}
+
+static __attribute__ ((noipa)) unsigned
+put_dec_helper4 (char *buf, unsigned x)
+{
+ uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43;
+ put_dec_full4(buf, x - q * 10000);
+ return q;
+}
+
+static __attribute__ ((noipa)) char *
+put_dec (char *buf, unsigned long long n)
+{
+ uint32_t d3, d2, d1, q, h;
+ d1 = ((uint32_t)n >> 16);
+ h = (n >> 32);
+ d2 = (h ) & 0xffff;
+ d3 = (h >> 16);
+ q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff);
+ q = put_dec_helper4(buf, q);
+ q += 7671 * d3 + 9496 * d2 + 6 * d1;
+ q = put_dec_helper4(buf+4, q);
+ q += 4749 * d3 + 42 * d2;
+ q = put_dec_helper4(buf+8, q);
+ return buf;
+}
+
+struct printf_spec {
+ unsigned int type:8;
+ signed int field_width:24;
+ unsigned int flags:8;
+ unsigned int base:8;
+ signed int precision:16;
+} __attribute__((__packed__));
+
+static __attribute__ ((noipa)) char *
+number (char *buf, char *end, unsigned long long num, struct printf_spec spec)
+{
+
+ char tmp[3 * sizeof(num)] __attribute__((__aligned__(2)));
+ char sign;
+ char locase;
+ int need_pfx = ((spec.flags & 64) && spec.base != 10);
+ int i;
+ bool is_zero = num == 0LL;
+ int field_width = spec.field_width;
+ int precision = spec.precision;
+
+ i = 0;
+ if (num < spec.base)
+ tmp[i++] = hex_asc_upper[num] | locase;
+ else if (spec.base != 10) {
+ int mask = spec.base - 1;
+ int shift = 3;
+ if (spec.base == 16)
+ shift = 4;
+ else
+ __builtin_abort ();
+ do {
+ tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] | locase);
+ num >>= shift;
+ } while (num);
+ } else {
+ i = put_dec(tmp, num) - tmp;
+ }
+ return buf;
+}
+
+static __attribute__ ((noipa)) char *
+pointer_string (char *buf, char *end, const void *ptr, struct printf_spec spec)
+{
+ spec.base = 16;
+ spec.flags = 0;
+ return number(buf, end, 100, spec);
+}
+
+int
+main (void)
+{
+ struct printf_spec spec;
+ char *s = pointer_string (0, 0, 0, spec);
+ return 0;
+}
|