mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 02:40:32 +08:00
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
This commit is contained in:
parent
257caa552b
commit
7ee98586a6
@ -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
|
||||
|
@ -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
|
||||
|
111
gcc/testsuite/gcc.c-torture/execute/20190820-1.c
Normal file
111
gcc/testsuite/gcc.c-torture/execute/20190820-1.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user