diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-03-22 14:38:42 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-03-22 14:38:42 +0000 |
commit | 19db1ec8f1712d5c6107f6795c82be163fda6c80 (patch) | |
tree | 07e38dec0fc55cf290a215c1b217490973866e7b | |
parent | de634e657fdb4fb88212863ef0a5d0f67aac977d (diff) | |
download | gcc-19db1ec8f1712d5c6107f6795c82be163fda6c80.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234405 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/genmatch.c | 72 | ||||
-rw-r--r-- | gcc/gimple-match-head.c | 1 | ||||
-rw-r--r-- | gcc/match.pd | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr70251.C | 11 |
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); +} |