summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr94482.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c50
-rw-r--r--gcc/tree-sra.c31
-rw-r--r--gcc/tree-ssa-forwprop.c6
6 files changed, 135 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d211d7391a8..368dfd6094e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2020-04-09 Martin Jambor <mjambor@suse.cz>
+ Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/94482
+ * tree-sra.c (create_access_replacement): Dump new replacement with
+ TDF_UID.
+ (sra_modify_expr): Fix handling of cases when the original EXPR writes
+ to only part of the replacement.
+ * tree-ssa-forwprop.c (pass_forwprop::execute): Properly verify
+ the first operand of combinations into REAL/IMAGPART_EXPR and
+ BIT_FIELD_REF.
+
2020-04-09 Richard Sandiford <richard.sandiford@arm.com>
* doc/sourcebuild.texi (check-function-bodies): Treat the third
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a5bd5614e5a..e01fdb0fe2c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2020-04-09 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/94482
+ * gcc.dg/torture/pr94482.c: New test.
+ * gcc.dg/tree-ssa/pr94482-2.c: Likewise.
+
2020-04-09 Marek Polacek <polacek@redhat.com>
PR c++/93790
diff --git a/gcc/testsuite/gcc.dg/torture/pr94482.c b/gcc/testsuite/gcc.dg/torture/pr94482.c
new file mode 100644
index 00000000000..d9ccaf39049
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr94482.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-options "-msse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-require-effective-target sse_runtime { target { i?86-*-* x86_64-*-* } } } */
+
+typedef unsigned V __attribute__ ((__vector_size__ (16)));
+union U
+{
+ V j;
+ unsigned long long i __attribute__ ((__vector_size__ (16)));
+};
+
+static inline __attribute__((always_inline)) V
+foo (unsigned long long a)
+{
+ union U z = { .j = (V) {} };
+ for (unsigned long i = 0; i < 1; i++)
+ z.i[i] = a;
+ return z.j;
+}
+
+static inline __attribute__((always_inline)) V
+bar (V a, unsigned long long i, int q)
+{
+ union U z = { .j = a };
+ z.i[q] = i;
+ return z.j;
+}
+
+int
+main ()
+{
+ union U z = { .j = bar (foo (1729), 2, 1) };
+ if (z.i[0] != 1729)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c
new file mode 100644
index 00000000000..fcac9d5e439
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+
+typedef unsigned long V __attribute__ ((__vector_size__ (8)));
+typedef _Complex int Ci;
+typedef _Complex float Cf;
+
+union U
+{
+ Ci ci;
+ Cf cf;
+};
+
+volatile Ci vgi;
+
+Cf foo (Cf c)
+{
+ __real c = 0x1ffp10;
+ return c;
+}
+
+Ci ioo (Ci c)
+{
+ __real c = 50;
+ return c;
+}
+
+
+int main (int argc, char *argv[])
+{
+ union U u;
+
+ __real u.ci = 500;
+ __imag u.ci = 1000;
+ vgi = u.ci;
+
+ u.ci = ioo (u.ci);
+ __imag u.ci = 100;
+
+ if (__real u.ci != 50 || __imag u.ci != 100)
+ __builtin_abort();
+
+ u.cf = foo (u.cf);
+ __imag u.cf = 0x1p3;
+
+ if (__real u.cf != 0x1ffp10 || __imag u.cf != 0x1p3)
+ __builtin_abort();
+
+ return 0;
+}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index b2056b58750..84c113c403c 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2257,7 +2257,7 @@ create_access_replacement (struct access *access, tree reg_type = NULL_TREE)
print_generic_expr (dump_file, access->base);
fprintf (dump_file, " offset: %u, size: %u: ",
(unsigned) access->offset, (unsigned) access->size);
- print_generic_expr (dump_file, repl);
+ print_generic_expr (dump_file, repl, TDF_UID);
fprintf (dump_file, "\n");
}
}
@@ -3698,6 +3698,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
location_t loc;
struct access *access;
tree type, bfr, orig_expr;
+ bool partial_cplx_access = false;
if (TREE_CODE (*expr) == BIT_FIELD_REF)
{
@@ -3708,7 +3709,10 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
bfr = NULL_TREE;
if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
- expr = &TREE_OPERAND (*expr, 0);
+ {
+ expr = &TREE_OPERAND (*expr, 0);
+ partial_cplx_access = true;
+ }
access = get_access_for_expr (*expr);
if (!access)
return false;
@@ -3736,13 +3740,32 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
be accessed as a different type too, potentially creating a need for
type conversion (see PR42196) and when scalarized unions are involved
in assembler statements (see PR42398). */
- if (!useless_type_conversion_p (type, access->type))
+ if (!bfr && !useless_type_conversion_p (type, access->type))
{
tree ref;
ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
- if (write)
+ if (partial_cplx_access)
+ {
+ /* VIEW_CONVERT_EXPRs in partial complex access are always fine in
+ the case of a write because in such case the replacement cannot
+ be a gimple register. In the case of a load, we have to
+ differentiate in between a register an non-register
+ replacement. */
+ tree t = build1 (VIEW_CONVERT_EXPR, type, repl);
+ gcc_checking_assert (!write || access->grp_partial_lhs);
+ if (!access->grp_partial_lhs)
+ {
+ tree tmp = make_ssa_name (type);
+ gassign *stmt = gimple_build_assign (tmp, t);
+ /* This is always a read. */
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ t = tmp;
+ }
+ *expr = t;
+ }
+ else if (write)
{
gassign *stmt;
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index e7eaa18ccad..3d8acf7eb03 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2815,7 +2815,8 @@ pass_forwprop::execute (function *fun)
continue;
if (!is_gimple_assign (use_stmt)
|| (gimple_assign_rhs_code (use_stmt) != REALPART_EXPR
- && gimple_assign_rhs_code (use_stmt) != IMAGPART_EXPR))
+ && gimple_assign_rhs_code (use_stmt) != IMAGPART_EXPR)
+ || TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) != lhs)
{
rewrite = false;
break;
@@ -2877,7 +2878,8 @@ pass_forwprop::execute (function *fun)
if (is_gimple_debug (use_stmt))
continue;
if (!is_gimple_assign (use_stmt)
- || gimple_assign_rhs_code (use_stmt) != BIT_FIELD_REF)
+ || gimple_assign_rhs_code (use_stmt) != BIT_FIELD_REF
+ || TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) != lhs)
{
rewrite = false;
break;