Patchwork Invalidate in cselib sp after processing frame_pointer_needed fp setter (PR rtl-optimization/54921)

login
register
mail settings
Submitter Jakub Jelinek
Date Oct. 23, 2012, 3:38 p.m.
Message ID <20121023153809.GR1752@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/193517/
State New
Headers show

Comments

Jakub Jelinek - Oct. 23, 2012, 3:38 p.m.
Hi!

This is an attempt to hopefully end the endless stream of aliasing
miscompilations where alias.c assumes that hfp based accesses
can't alias sp based accesses, but both sp and fp can appear in VALUEs
pretty much randomly.  As detailed in the PR, we have the r variable
at rbp - 48 and rsp is also rbp - 48, some stores use direct rbp - 44
based addresses which then have find_base_term of the value equal
to (address:DI -4), other stores use rdi == r9 based address,
where r9 is r8 + 4 and r8 is rbp - 48, but value for r8 has
r8 as well as rsp registers in its locs and therefore
find_base_term returns (address:DI -1) - i.e. sp based term,
and alias.c says those two can't alias even when they actually do.

The fix is what I've done recently in var-tracking.c, invalidate
sp if frame_pointer_needed right after the fp setter insn, so we
then have a set of VALUEs which are based on rbp and a different set of
values which are based on rsp, but those two sets are now disjoint.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2012-10-23  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/54921
	* cselib.c (cselib_process_insn): If frame_pointer_needed,
	call cselib_invalidate_rtx (stack_pointer_rtx) after
	processing a frame pointer setter in the prologue.

	* gcc.dg/pr54921.c: New test.


	Jakub

Patch

--- gcc/cselib.c.jj	2012-10-16 13:20:25.000000000 +0200
+++ gcc/cselib.c	2012-10-23 14:22:17.694861625 +0200
@@ -2655,6 +2655,34 @@  cselib_process_insn (rtx insn)
       if (GET_CODE (XEXP (x, 0)) == CLOBBER)
 	cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
 
+  /* On setter of the hard frame pointer if frame_pointer_needed,
+     invalidate stack_pointer_rtx, so that sp and {,h}fp based
+     VALUEs are distinct.  */
+  if (reload_completed
+      && frame_pointer_needed
+      && RTX_FRAME_RELATED_P (insn)
+      && BLOCK_FOR_INSN (insn) == single_succ (ENTRY_BLOCK_PTR))
+    {
+      rtx pat = PATTERN (insn);
+      rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
+      if (expr)
+	pat = XEXP (expr, 0);
+      if (GET_CODE (pat) == SET
+	  && SET_DEST (pat) == hard_frame_pointer_rtx)
+	cselib_invalidate_rtx (stack_pointer_rtx);
+      else if (GET_CODE (pat) == PARALLEL)
+	{
+	  int i;
+	  for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
+	    if (GET_CODE (XVECEXP (pat, 0, i)) == SET
+		&& SET_DEST (XVECEXP (pat, 0, i)) == hard_frame_pointer_rtx)
+	      {
+		cselib_invalidate_rtx (stack_pointer_rtx);
+		break;
+	      }
+	}
+    }
+
   cselib_current_insn = NULL_RTX;
 
   if (n_useless_values > MAX_USELESS_VALUES
--- gcc/testsuite/gcc.dg/pr54921.c.jj	2012-10-23 14:17:49.811466882 +0200
+++ gcc/testsuite/gcc.dg/pr54921.c	2012-10-23 14:17:32.000000000 +0200
@@ -0,0 +1,32 @@ 
+/* PR rtl-optimization/54921 */
+/* { dg-do run } */
+/* { dg-options "-Os -fno-omit-frame-pointer -fsched2-use-superblocks -ftree-slp-vectorize" } */
+/* { dg-additional-options "-fstack-protector" { target fstack_protector } } */
+
+struct A
+{
+  int a;
+  char b[32];
+} a, b;
+
+__attribute__((noinline, noclone))
+struct A
+bar (int x)
+{
+  struct A r;
+  static int n;
+  r.a = ++n;
+  __builtin_memset (r.b, 0, sizeof (r.b));
+  r.b[0] = x;
+  return r;
+}
+
+int
+main ()
+{
+  a = bar (3);
+  b = bar (4);
+  if (a.a != 1 || a.b[0] != 3 || b.a != 2 || b.b[0] != 4)
+    __builtin_abort ();
+  return 0;
+}