diff mbox

Fix PR65077

Message ID alpine.LSU.2.11.1502161555400.27763@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Feb. 16, 2015, 2:56 p.m. UTC
The following removes an optimization not considering FP values
to carry pointers from PTA.  Instead to fix the underlying problem
in PR37021 this patch adds handling of the rest of handled_components_p.

Bootstrap and regtest in progress on x86_64-unknown-linux-gnu.

Richard.

2015-02-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/65077
	* tree-ssa-structalias.c (get_constraint_for_1): Handle
	IMAGPART_EXPR, REALPART_EXPR and BIT_FIELD_REF.
	(find_func_aliases): Allow float values to carry pointers again.

	* gcc.dg/torture/pr65077.c: New testcase.
diff mbox

Patch

Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c	(revision 220731)
+++ gcc/tree-ssa-structalias.c	(working copy)
@@ -3492,6 +3492,9 @@  get_constraint_for_1 (tree t, vec<ce_s>
 	  case ARRAY_REF:
 	  case ARRAY_RANGE_REF:
 	  case COMPONENT_REF:
+	  case IMAGPART_EXPR:
+	  case REALPART_EXPR:
+	  case BIT_FIELD_REF:
 	    get_constraint_for_component_ref (t, results, address_p, lhs_p);
 	    return;
 	  case VIEW_CONVERT_EXPR:
@@ -4712,11 +4811,7 @@  find_func_aliases (struct function *fn,
 
 	  get_constraint_for (lhsop, &lhsc);
 
-	  if (FLOAT_TYPE_P (TREE_TYPE (lhsop)))
-	    /* If the operation produces a floating point result then
-	       assume the value is not produced to transfer a pointer.  */
-	    ;
-	  else if (code == POINTER_PLUS_EXPR)
+	  if (code == POINTER_PLUS_EXPR)
 	    get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
 					   gimple_assign_rhs2 (t), &rhsc);
 	  else if (code == BIT_AND_EXPR
Index: gcc/testsuite/gcc.dg/torture/pr65077.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr65077.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr65077.c	(working copy)
@@ -0,0 +1,70 @@ 
+/* { dg-do run } */
+
+extern void abort (void);
+extern void *memcpy(void *, const void *, __SIZE_TYPE__);
+
+typedef struct {
+    void *v1;
+    void *v2;
+    void *v3;
+    union {
+	void *f1;
+	void *f2;
+    } u;
+} S;
+
+
+S *getS();
+void verify_p(void *p);
+double *getP(void *p);
+
+void memcpy_bug()
+{
+  S *s;
+  double *p = getP(0);
+
+  if (p) {
+      int intSptr[sizeof(S*)/sizeof(int)];
+      unsigned i = 0;
+      for (i = 0; i < sizeof(intSptr)/sizeof(*intSptr); ++i) {
+	  intSptr[i] = (int) p[i];
+      }
+      memcpy(&s, intSptr, sizeof(intSptr));
+      (s)->u.f1 = p;
+      verify_p((s)->u.f1);      
+  } else {
+      s = getS();
+  }
+  verify_p(s->u.f1);
+}
+
+double P[4];
+
+double *getP(void *p) {
+    union u {
+	void *p;
+	int i[2];
+    } u;
+    u.p = P;
+    P[0] = u.i[0];
+    P[1] = u.i[1];
+    return P;
+}
+
+S *getS()
+{
+  return 0;
+}
+
+void verify_p(void *p)
+{
+  if (p != P)
+    abort ();
+}
+
+int main(int argc, char *argv[])
+{
+    memcpy_bug();
+    return 0;
+}
+