aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-03-22 14:38:42 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-03-22 14:38:42 +0000
commita3ca1bc5bd6bdded34df1040fdb595c4de032071 (patch)
tree07e38dec0fc55cf290a215c1b217490973866e7b /gcc
parentec613b6634d57abc9402ba8c51bdbc9f59807690 (diff)
re PR tree-optimization/70251 (Wrong code with -O3 -march=skylake-avx512.)
2016-03-22 Richard Biener <rguenther@suse.de> PR middle-end/70251 * genmatch.c (gen_transform): Adjust last parameter to a three-state int... (capture::gen_transform): ... to change behavior when substituting a condition into cond or not-cond expr context. (dt_simplify::gen_1): Adjust. * gimple-match-head.c: Include gimplify.h for unshare_expr. * match.pd (A + (B vcmp C ? 1 : 0) -> A - (B vcmp C)): Revert last change and instead change to A + (B vcmp C ? 1 : 0) -> A - (B vcmp C ? -1 : 0). (A - (B vcmp C ? 1 : 0) -> A + (B vcmp C)): Likewise. * g++.dg/torture/pr70251.C: New testcase. From-SVN: r234405
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/genmatch.c72
-rw-r--r--gcc/gimple-match-head.c1
-rw-r--r--gcc/match.pd16
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr70251.C11
6 files changed, 76 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 57c325d1ab5..92391efd907 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2016-03-22 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/70251
+ * genmatch.c (gen_transform): Adjust last parameter to a three-state
+ int...
+ (capture::gen_transform): ... to change behavior when substituting
+ a condition into cond or not-cond expr context.
+ (dt_simplify::gen_1): Adjust.
+ * gimple-match-head.c: Include gimplify.h for unshare_expr.
+ * match.pd (A + (B vcmp C ? 1 : 0) -> A - (B vcmp C)): Revert
+ last change and instead change to
+ A + (B vcmp C ? 1 : 0) -> A - (B vcmp C ? -1 : 0).
+ (A - (B vcmp C ? 1 : 0) -> A + (B vcmp C)): Likewise.
+
2016-03-22 Anthony Green <green@moxielogic.com>
* config/moxie/moxiebox.h (CC1_SPEC): Define. Fix endianness
diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index bb97bfb642c..1f5f45c206a 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -548,7 +548,7 @@ struct operand {
virtual void gen_transform (FILE *, int, const char *, bool, int,
const char *, capture_info *,
dt_operand ** = 0,
- bool = true)
+ int = 0)
{ gcc_unreachable (); }
};
@@ -590,7 +590,7 @@ struct expr : public operand
bool force_single_use;
virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *,
- dt_operand ** = 0, bool = true);
+ dt_operand ** = 0, int = 0);
};
/* An operator that is represented by native C code. This is always
@@ -622,7 +622,7 @@ struct c_expr : public operand
vec<id_tab> ids;
virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *,
- dt_operand ** = 0, bool = true);
+ dt_operand ** = 0, int = 0);
};
/* A wrapper around another operand that captures its value. */
@@ -637,7 +637,7 @@ struct capture : public operand
operand *what;
virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *,
- dt_operand ** = 0, bool = true);
+ dt_operand ** = 0, int = 0);
};
/* if expression. */
@@ -2149,7 +2149,7 @@ get_operand_type (id_base *op, const char *in_type,
void
expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
int depth, const char *in_type, capture_info *cinfo,
- dt_operand **indexes, bool)
+ dt_operand **indexes, int)
{
id_base *opr = operation;
/* When we delay operator substituting during lowering of fors we
@@ -2213,9 +2213,8 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
i == 0 ? NULL : op0type);
ops[i]->gen_transform (f, indent, dest, gimple, depth + 1, optype,
cinfo, indexes,
- ((!(*opr == COND_EXPR)
- && !(*opr == VEC_COND_EXPR))
- || i != 0));
+ (*opr == COND_EXPR
+ || *opr == VEC_COND_EXPR) && i == 0 ? 1 : 2);
}
const char *opr_name;
@@ -2306,7 +2305,7 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
void
c_expr::gen_transform (FILE *f, int indent, const char *dest,
bool, int, const char *, capture_info *,
- dt_operand **, bool)
+ dt_operand **, int)
{
if (dest && nr_stmts == 1)
fprintf_indent (f, indent, "%s = ", dest);
@@ -2378,7 +2377,7 @@ c_expr::gen_transform (FILE *f, int indent, const char *dest,
void
capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
int depth, const char *in_type, capture_info *cinfo,
- dt_operand **indexes, bool expand_compares)
+ dt_operand **indexes, int cond_handling)
{
if (what && is_a<expr *> (what))
{
@@ -2394,20 +2393,29 @@ capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
fprintf_indent (f, indent, "%s = captures[%u];\n", dest, where);
/* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
- with substituting a capture of that.
- ??? Returning false here will also not allow any other patterns
- to match. */
- if (gimple && expand_compares
+ with substituting a capture of that. */
+ if (gimple
+ && cond_handling != 0
&& cinfo->info[where].cond_expr_cond_p)
{
- fprintf_indent (f, indent, "if (COMPARISON_CLASS_P (%s))\n", dest);
- fprintf_indent (f, indent, " {\n");
- fprintf_indent (f, indent, " if (!seq) return false;\n");
- fprintf_indent (f, indent, " %s = gimple_build (seq, TREE_CODE (%s),"
- " TREE_TYPE (%s), TREE_OPERAND (%s, 0),"
- " TREE_OPERAND (%s, 1));\n",
- dest, dest, dest, dest, dest);
- fprintf_indent (f, indent, " }\n");
+ /* If substituting into a cond_expr condition, unshare. */
+ if (cond_handling == 1)
+ fprintf_indent (f, indent, "%s = unshare_expr (%s);\n", dest, dest);
+ /* If substituting elsewhere we might need to decompose it. */
+ else if (cond_handling == 2)
+ {
+ /* ??? Returning false here will also not allow any other patterns
+ to match unless this generator was split out. */
+ fprintf_indent (f, indent, "if (COMPARISON_CLASS_P (%s))\n", dest);
+ fprintf_indent (f, indent, " {\n");
+ fprintf_indent (f, indent, " if (!seq) return false;\n");
+ fprintf_indent (f, indent, " %s = gimple_build (seq,"
+ " TREE_CODE (%s),"
+ " TREE_TYPE (%s), TREE_OPERAND (%s, 0),"
+ " TREE_OPERAND (%s, 1));\n",
+ dest, dest, dest, dest, dest);
+ fprintf_indent (f, indent, " }\n");
+ }
}
}
@@ -3043,18 +3051,14 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result)
"type", e->expr_type,
j == 0 ? NULL : "TREE_TYPE (res_ops[0])");
/* We need to expand GENERIC conditions we captured from
- COND_EXPRs. */
- bool expand_generic_cond_exprs_p
- = (!is_predicate
- /* But avoid doing that if the GENERIC condition is
- valid - which it is in the first operand of COND_EXPRs
- and VEC_COND_EXRPs. */
- && ((!(*opr == COND_EXPR)
- && !(*opr == VEC_COND_EXPR))
- || j != 0));
+ COND_EXPRs and we need to unshare them when substituting
+ into COND_EXPRs. */
+ int cond_handling = 0;
+ if (!is_predicate)
+ cond_handling = ((*opr == COND_EXPR
+ || *opr == VEC_COND_EXPR) && j == 0) ? 1 : 2;
e->ops[j]->gen_transform (f, indent, dest, true, 1, optype,
- &cinfo,
- indexes, expand_generic_cond_exprs_p);
+ &cinfo, indexes, cond_handling);
}
/* Re-fold the toplevel result. It's basically an embedded
@@ -3068,7 +3072,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result)
|| result->type == operand::OP_C_EXPR)
{
result->gen_transform (f, indent, "res_ops[0]", true, 1, "type",
- &cinfo, indexes, false);
+ &cinfo, indexes);
fprintf_indent (f, indent, "*res_code = TREE_CODE (res_ops[0]);\n");
if (is_a <capture *> (result)
&& cinfo.info[as_a <capture *> (result)->where].cond_expr_cond_p)
diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
index 3e6d15f1b36..c86a4ffb0e3 100644
--- a/gcc/gimple-match-head.c
+++ b/gcc/gimple-match-head.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "internal-fn.h"
#include "case-cfn-macros.h"
+#include "gimplify.h"
/* Forward declarations of the private auto-generated matchers.
diff --git a/gcc/match.pd b/gcc/match.pd
index ddb4b8a7885..388a489dcb8 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1752,28 +1752,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cnd (logical_inverted_value truth_valued_p@0) @1 @2)
(cnd @0 @2 @1)))
-/* A + (B vcmp C ? 1 : 0) -> A - (B vcmp C), since vector comparisons
- return all-1 or all-0 results. */
+/* A + (B vcmp C ? 1 : 0) -> A - (B vcmp C ? -1 : 0), since vector comparisons
+ return all -1 or all 0 results. */
/* ??? We could instead convert all instances of the vec_cond to negate,
but that isn't necessarily a win on its own. */
(simplify
- (plus:c @3 (view_convert? (vec_cond @0 integer_each_onep@1 integer_zerop@2)))
+ (plus:c @3 (view_convert? (vec_cond:s @0 integer_each_onep@1 integer_zerop@2)))
(if (VECTOR_TYPE_P (type)
- && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (@0)))
&& TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0))
&& (TYPE_MODE (TREE_TYPE (type))
== TYPE_MODE (TREE_TYPE (TREE_TYPE (@0)))))
- (minus @3 (view_convert @0))))
+ (minus @3 (view_convert (vec_cond @0 (negate @1) @2)))))
-/* ... likewise A - (B vcmp C ? 1 : 0) -> A + (B vcmp C). */
+/* ... likewise A - (B vcmp C ? 1 : 0) -> A + (B vcmp C ? -1 : 0). */
(simplify
- (minus @3 (view_convert? (vec_cond @0 integer_each_onep@1 integer_zerop@2)))
+ (minus @3 (view_convert? (vec_cond:s @0 integer_each_onep@1 integer_zerop@2)))
(if (VECTOR_TYPE_P (type)
- && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (@0)))
&& TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0))
&& (TYPE_MODE (TREE_TYPE (type))
== TYPE_MODE (TREE_TYPE (TREE_TYPE (@0)))))
- (plus @3 (view_convert @0))))
+ (plus @3 (view_convert (vec_cond @0 (negate @1) @2)))))
/* Simplifications of comparisons. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cbf14803368..00c82625bef 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-03-22 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/70251
+ * g++.dg/torture/pr70251.C: New testcase.
+
2016-03-22 David Malcolm <dmalcolm@redhat.com>
PR c/69993
diff --git a/gcc/testsuite/g++.dg/torture/pr70251.C b/gcc/testsuite/g++.dg/torture/pr70251.C
new file mode 100644
index 00000000000..5af35b2d8cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr70251.C
@@ -0,0 +1,11 @@
+// { dg-do compile }
+// { dg-additional-options "-w -Wno-psabi" }
+
+typedef int vec __attribute__((vector_size(64)));
+vec f(vec x,vec y,vec z)
+{
+ vec zero={};
+ vec one=zero+1;
+ vec c=x<y;
+ return z+(c?one:zero);
+}