This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR rtl-optimization/91347


This is a regression present on all active branches: the compiler generates 
wrong code when tail cail optimization is used on the HPPA because the RTL DSE 
passes incorrectly deletes a live store.  The fix completes the previous fix 
by Jakub for PR rtl-opt/55023 by extending the treatment applied to some tail 
calls before reload to all tail calls if HARD_FRAME_POINTER_IS_ARG_POINTER.

Tested by Dave on HPPA/Linux, applied on all active branches.


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  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.c-torture/execute/20190820-1.c: New test.

-- 
Eric Botcazou
Index: dse.c
===================================================================
--- dse.c	(revision 274487)
+++ dse.c	(working copy)
@@ -2537,10 +2537,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
/* 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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]