From: Eric Botcazou Date: Tue, 20 Aug 2019 09:10:53 +0000 (+0000) Subject: re PR rtl-optimization/91347 (hppa: wrong code generated with tail call optimisation) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7ee98586a66efe3219ef5a8b00bcced4b0da23e5;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd9838f2678..7130cdab526 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-20 Eric Botcazou + + 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 * calls.h (function_arg_info): Add a pass_by_reference field, diff --git a/gcc/dse.c b/gcc/dse.c index 7511f71b9c0..5e270f9a5b4 100644 --- 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9dee58caad3..e4cc820f0f7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-20 Eric Botcazou + + * gcc.c-torture/execute/20190820-1.c: New test. + 2019-08-20 Richard Biener 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 00000000000..6a06eff7571 --- /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 */ + +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; +}