2018-11-26 Richard Biener <rguenther@suse.de>
Backport from mainline
2018-10-15 Richard Biener <rguenther@suse.de>
PR middle-end/87610
* tree-ssa-structalias.c (struct vls_data): Add escaped_p member.
(visit_loadstore): When a used restrict tag escaped verify that
the points-to solution of "other" pointers do not include
escaped.
(compute_dependence_clique): If a used restrict tag escaped
communicated that down to visit_loadstore.
* gcc.dg/torture/restrict-6.c: New testcase.
2018-10-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/87665
PR tree-optimization/87745
* tree-vectorizer.h (get_earlier_stmt): Remove.
(get_later_stmt): Pick up UID from the original non-pattern stmt.
* gfortran.dg/
20181025-1.f: New testcase.
2018-10-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/87665
* tree-vect-data-refs.c (vect_preserves_scalar_order_p): Adjust
to reflect reality.
* gcc.dg/torture/pr87665.c: New testcase.
From-SVN: r266460
+2018-11-26 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2018-10-15 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/87610
+ * tree-ssa-structalias.c (struct vls_data): Add escaped_p member.
+ (visit_loadstore): When a used restrict tag escaped verify that
+ the points-to solution of "other" pointers do not include
+ escaped.
+ (compute_dependence_clique): If a used restrict tag escaped
+ communicated that down to visit_loadstore.
+
+ 2018-10-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/87665
+ PR tree-optimization/87745
+ * tree-vectorizer.h (get_earlier_stmt): Remove.
+ (get_later_stmt): Pick up UID from the original non-pattern stmt.
+
+ 2018-10-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/87665
+ * tree-vect-data-refs.c (vect_preserves_scalar_order_p): Adjust
+ to reflect reality.
+
2018-11-26 Richard Biener <rguenther@suse.de>
Backport from mainline
+2018-11-26 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2018-10-15 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/87610
+ * gcc.dg/torture/restrict-6.c: New testcase.
+
+ 2018-10-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/87665
+ PR tree-optimization/87745
+ * gfortran.dg/20181025-1.f: New testcase.
+
+ 2018-10-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/87665
+ * gcc.dg/torture/pr87665.c: New testcase.
+
2018-11-26 Richard Biener <rguenther@suse.de>
Backport from mainline
--- /dev/null
+/* { dg-do run } */
+
+struct X { long x; long y; };
+
+struct X a[1024], b[1024];
+
+void foo ()
+{
+ for (int i = 0; i < 1024; ++i)
+ {
+ long tem = a[i].x;
+ a[i].x = 0;
+ b[i].x = tem;
+ b[i].y = a[i].y;
+ }
+}
+
+int main()
+{
+ for (int i = 0; i < 1024; ++i)
+ a[i].x = i;
+ foo ();
+ for (int i = 0; i < 1024; ++i)
+ if (b[i].x != i)
+ __builtin_abort();
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+
+extern void abort (void);
+
+void __attribute__((noinline)) g(int **a, int *b)
+{
+ *a = b;
+}
+
+int foo(int * restrict p, int *q)
+{
+ g(&q, p);
+ *p = 1;
+ *q = 2;
+ return *p + *q;
+}
+
+int main()
+{
+ int x, y;
+ if (foo(&x, &y) != 4)
+ abort ();
+ return 0;
+}
--- /dev/null
+! { dg-do compile }
+! { dg-options "-Ofast" }
+! { dg-additional-options "-mavx2" { target { x86_64-*-* i?86-*-* } } }
+ SUBROUTINE FOO(EF3,CA,ZA,NATA,IC4,NFRGPT)
+ IMPLICIT DOUBLE PRECISION (A-H,O-Z)
+ PARAMETER (MXATM=500)
+ COMMON DE(3,MXATM)
+ DIMENSION CA(3,NATA)
+ DIMENSION ZA(NATA)
+ DIMENSION EF3(3,NFRGPT)
+ DO II = 1,NATA
+ XII = XJ - CA(1,II)
+ YII = YJ - CA(2,II)
+ ZII = ZJ - CA(3,II)
+ RJII = SQRT(XII*XII + YII*YII + ZII*ZII)
+ R3 = RJII*RJII*RJII
+ IF (IC4.EQ.0) THEN
+ DE(1,II) = DE(1,II) - S2*ZA(II)*XII/R3
+ DE(2,II) = DE(2,II) - S2*ZA(II)*YII/R3
+ DE(3,II) = DE(3,II) - S2*ZA(II)*ZII/R3
+ ELSE
+ EF3(1,IC4+II) = EF3(1,IC4+II) - S2*ZA(II)*XII/R3
+ EF3(2,IC4+II) = EF3(2,IC4+II) - S2*ZA(II)*YII/R3
+ EF3(3,IC4+II) = EF3(3,IC4+II) - S2*ZA(II)*ZII/R3
+ END IF
+ END DO
+ RETURN
+ END
struct vls_data
{
unsigned short clique;
+ bool escaped_p;
bitmap rvars;
};
{
unsigned short clique = ((vls_data *) data)->clique;
bitmap rvars = ((vls_data *) data)->rvars;
+ bool escaped_p = ((vls_data *) data)->escaped_p;
if (TREE_CODE (base) == MEM_REF
|| TREE_CODE (base) == TARGET_MEM_REF)
{
return false;
vi = get_varinfo (find (vi->id));
- if (bitmap_intersect_p (rvars, vi->solution))
+ if (bitmap_intersect_p (rvars, vi->solution)
+ || (escaped_p && bitmap_bit_p (vi->solution, escaped_id)))
return false;
}
unsigned short clique = 0;
unsigned short last_ruid = 0;
bitmap rvars = BITMAP_ALLOC (NULL);
+ bool escaped_p = false;
for (unsigned i = 0; i < num_ssa_names; ++i)
{
tree ptr = ssa_name (i);
last_ruid);
}
if (used)
- bitmap_set_bit (rvars, restrict_var->id);
+ {
+ bitmap_set_bit (rvars, restrict_var->id);
+ varinfo_t escaped = get_varinfo (find (escaped_id));
+ if (bitmap_bit_p (escaped->solution, restrict_var->id))
+ escaped_p = true;
+ }
}
}
parameters) we can't restrict scoping properly thus the following
is too aggressive there. For now we have excluded those globals from
getting into the MR_DEPENDENCE machinery. */
- vls_data data = { clique, rvars };
+ vls_data data = { clique, escaped_p, rvars };
basic_block bb;
FOR_EACH_BB_FN (bb, cfun)
for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
}
+/* Return true if we know that the order of vectorized STMT_A and
+ vectorized STMT_B will be the same as the order of STMT_A and STMT_B.
+ At least one of the statements is a write. */
+
+static bool
+vect_preserves_scalar_order_p (gimple *stmt_a, gimple *stmt_b)
+{
+ stmt_vec_info stmtinfo_a = vinfo_for_stmt (stmt_a);
+ stmt_vec_info stmtinfo_b = vinfo_for_stmt (stmt_b);
+
+ /* Single statements are always kept in their original order. */
+ if (!STMT_VINFO_GROUPED_ACCESS (stmtinfo_a)
+ && !STMT_VINFO_GROUPED_ACCESS (stmtinfo_b))
+ return true;
+
+ /* STMT_A and STMT_B belong to overlapping groups. All loads in a
+ group are emitted at the position of the last scalar load and all
+ stores in a group are emitted at the position of the last scalar store.
+ Compute that position and check whether the resulting order matches
+ the current one. */
+ gimple *last_a = GROUP_FIRST_ELEMENT (stmtinfo_a);
+ if (last_a)
+ for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_a)); s;
+ s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
+ last_a = get_later_stmt (last_a, s);
+ else
+ last_a = stmt_a;
+ gimple *last_b = GROUP_FIRST_ELEMENT (stmtinfo_b);
+ if (last_b)
+ for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_b)); s;
+ s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
+ last_b = get_later_stmt (last_b, s);
+ else
+ last_b = stmt_b;
+ return ((get_later_stmt (last_a, last_b) == last_a)
+ == (get_later_stmt (stmt_a, stmt_b) == stmt_a));
+}
+
+
/* Function vect_analyze_data_ref_dependence.
Return TRUE if there (might) exist a dependence between a memory-reference
... = a[i];
a[i+1] = ...;
where loads from the group interleave with the store. */
- if (STMT_VINFO_GROUPED_ACCESS (stmtinfo_a)
- || STMT_VINFO_GROUPED_ACCESS (stmtinfo_b))
+ if (!vect_preserves_scalar_order_p (DR_STMT (dra), DR_STMT (drb)))
{
- gimple *earlier_stmt;
- earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
- if (DR_IS_WRITE
- (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "READ_WRITE dependence in interleaving."
- "\n");
- return true;
- }
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "READ_WRITE dependence in interleaving."
+ "\n");
+ return true;
}
unsigned int step_prec = TYPE_PRECISION (TREE_TYPE (DR_STEP (dra)));
}
}
-/* Return the earlier statement between STMT1 and STMT2. */
+/* Return TRUE if a statement represented by STMT_INFO is a part of a
+ pattern. */
-static inline gimple *
-get_earlier_stmt (gimple *stmt1, gimple *stmt2)
+static inline bool
+is_pattern_stmt_p (stmt_vec_info stmt_info)
{
- unsigned int uid1, uid2;
-
- if (stmt1 == NULL)
- return stmt2;
-
- if (stmt2 == NULL)
- return stmt1;
-
- uid1 = gimple_uid (stmt1);
- uid2 = gimple_uid (stmt2);
-
- if (uid1 == 0 || uid2 == 0)
- return NULL;
+ gimple *related_stmt;
+ stmt_vec_info related_stmt_info;
- gcc_checking_assert (uid1 <= stmt_vec_info_vec.length ()
- && uid2 <= stmt_vec_info_vec.length ());
+ related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
+ if (related_stmt
+ && (related_stmt_info = vinfo_for_stmt (related_stmt))
+ && STMT_VINFO_IN_PATTERN_P (related_stmt_info))
+ return true;
- if (uid1 < uid2)
- return stmt1;
- else
- return stmt2;
+ return false;
}
/* Return the later statement between STMT1 and STMT2. */
if (stmt2 == NULL)
return stmt1;
- uid1 = gimple_uid (stmt1);
- uid2 = gimple_uid (stmt2);
+ stmt_vec_info stmt_info1 = vinfo_for_stmt (stmt1);
+ stmt_vec_info stmt_info2 = vinfo_for_stmt (stmt2);
+ uid1 = gimple_uid (is_pattern_stmt_p (stmt_info1)
+ ? STMT_VINFO_RELATED_STMT (stmt_info1) : stmt1);
+ uid2 = gimple_uid (is_pattern_stmt_p (stmt_info2)
+ ? STMT_VINFO_RELATED_STMT (stmt_info2) : stmt2);
if (uid1 == 0 || uid2 == 0)
return NULL;
return stmt2;
}
-/* Return TRUE if a statement represented by STMT_INFO is a part of a
- pattern. */
-
-static inline bool
-is_pattern_stmt_p (stmt_vec_info stmt_info)
-{
- gimple *related_stmt;
- stmt_vec_info related_stmt_info;
-
- related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
- if (related_stmt
- && (related_stmt_info = vinfo_for_stmt (related_stmt))
- && STMT_VINFO_IN_PATTERN_P (related_stmt_info))
- return true;
-
- return false;
-}
-
/* Return true if BB is a loop header. */
static inline bool