Commit a3ca1bc5 by Richard Biener Committed by Richard Biener

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
parent ec613b66
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> 2016-03-22 Anthony Green <green@moxielogic.com>
* config/moxie/moxiebox.h (CC1_SPEC): Define. Fix endianness * config/moxie/moxiebox.h (CC1_SPEC): Define. Fix endianness
......
...@@ -548,7 +548,7 @@ struct operand { ...@@ -548,7 +548,7 @@ struct operand {
virtual void gen_transform (FILE *, int, const char *, bool, int, virtual void gen_transform (FILE *, int, const char *, bool, int,
const char *, capture_info *, const char *, capture_info *,
dt_operand ** = 0, dt_operand ** = 0,
bool = true) int = 0)
{ gcc_unreachable (); } { gcc_unreachable (); }
}; };
...@@ -590,7 +590,7 @@ struct expr : public operand ...@@ -590,7 +590,7 @@ struct expr : public operand
bool force_single_use; bool force_single_use;
virtual void gen_transform (FILE *f, int, const char *, bool, int, virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *, 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 /* An operator that is represented by native C code. This is always
...@@ -622,7 +622,7 @@ struct c_expr : public operand ...@@ -622,7 +622,7 @@ struct c_expr : public operand
vec<id_tab> ids; vec<id_tab> ids;
virtual void gen_transform (FILE *f, int, const char *, bool, int, virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *, const char *, capture_info *,
dt_operand ** = 0, bool = true); dt_operand ** = 0, int = 0);
}; };
/* A wrapper around another operand that captures its value. */ /* A wrapper around another operand that captures its value. */
...@@ -637,7 +637,7 @@ struct capture : public operand ...@@ -637,7 +637,7 @@ struct capture : public operand
operand *what; operand *what;
virtual void gen_transform (FILE *f, int, const char *, bool, int, virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *, const char *, capture_info *,
dt_operand ** = 0, bool = true); dt_operand ** = 0, int = 0);
}; };
/* if expression. */ /* if expression. */
...@@ -2149,7 +2149,7 @@ get_operand_type (id_base *op, const char *in_type, ...@@ -2149,7 +2149,7 @@ get_operand_type (id_base *op, const char *in_type,
void void
expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple, expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
int depth, const char *in_type, capture_info *cinfo, int depth, const char *in_type, capture_info *cinfo,
dt_operand **indexes, bool) dt_operand **indexes, int)
{ {
id_base *opr = operation; id_base *opr = operation;
/* When we delay operator substituting during lowering of fors we /* 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, ...@@ -2213,9 +2213,8 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
i == 0 ? NULL : op0type); i == 0 ? NULL : op0type);
ops[i]->gen_transform (f, indent, dest, gimple, depth + 1, optype, ops[i]->gen_transform (f, indent, dest, gimple, depth + 1, optype,
cinfo, indexes, cinfo, indexes,
((!(*opr == COND_EXPR) (*opr == COND_EXPR
&& !(*opr == VEC_COND_EXPR)) || *opr == VEC_COND_EXPR) && i == 0 ? 1 : 2);
|| i != 0));
} }
const char *opr_name; const char *opr_name;
...@@ -2306,7 +2305,7 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple, ...@@ -2306,7 +2305,7 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
void void
c_expr::gen_transform (FILE *f, int indent, const char *dest, c_expr::gen_transform (FILE *f, int indent, const char *dest,
bool, int, const char *, capture_info *, bool, int, const char *, capture_info *,
dt_operand **, bool) dt_operand **, int)
{ {
if (dest && nr_stmts == 1) if (dest && nr_stmts == 1)
fprintf_indent (f, indent, "%s = ", dest); fprintf_indent (f, indent, "%s = ", dest);
...@@ -2378,7 +2377,7 @@ c_expr::gen_transform (FILE *f, int indent, const char *dest, ...@@ -2378,7 +2377,7 @@ c_expr::gen_transform (FILE *f, int indent, const char *dest,
void void
capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple, capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
int depth, const char *in_type, capture_info *cinfo, 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)) if (what && is_a<expr *> (what))
{ {
...@@ -2394,20 +2393,29 @@ capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple, ...@@ -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); fprintf_indent (f, indent, "%s = captures[%u];\n", dest, where);
/* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
with substituting a capture of that. with substituting a capture of that. */
??? Returning false here will also not allow any other patterns if (gimple
to match. */ && cond_handling != 0
if (gimple && expand_compares
&& cinfo->info[where].cond_expr_cond_p) && cinfo->info[where].cond_expr_cond_p)
{ {
fprintf_indent (f, indent, "if (COMPARISON_CLASS_P (%s))\n", dest); /* If substituting into a cond_expr condition, unshare. */
fprintf_indent (f, indent, " {\n"); if (cond_handling == 1)
fprintf_indent (f, indent, " if (!seq) return false;\n"); fprintf_indent (f, indent, "%s = unshare_expr (%s);\n", dest, dest);
fprintf_indent (f, indent, " %s = gimple_build (seq, TREE_CODE (%s)," /* If substituting elsewhere we might need to decompose it. */
" TREE_TYPE (%s), TREE_OPERAND (%s, 0)," else if (cond_handling == 2)
" TREE_OPERAND (%s, 1));\n", {
dest, dest, dest, dest, dest); /* ??? Returning false here will also not allow any other patterns
fprintf_indent (f, indent, " }\n"); 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) ...@@ -3043,18 +3051,14 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result)
"type", e->expr_type, "type", e->expr_type,
j == 0 ? NULL : "TREE_TYPE (res_ops[0])"); j == 0 ? NULL : "TREE_TYPE (res_ops[0])");
/* We need to expand GENERIC conditions we captured from /* We need to expand GENERIC conditions we captured from
COND_EXPRs. */ COND_EXPRs and we need to unshare them when substituting
bool expand_generic_cond_exprs_p into COND_EXPRs. */
= (!is_predicate int cond_handling = 0;
/* But avoid doing that if the GENERIC condition is if (!is_predicate)
valid - which it is in the first operand of COND_EXPRs cond_handling = ((*opr == COND_EXPR
and VEC_COND_EXRPs. */ || *opr == VEC_COND_EXPR) && j == 0) ? 1 : 2;
&& ((!(*opr == COND_EXPR)
&& !(*opr == VEC_COND_EXPR))
|| j != 0));
e->ops[j]->gen_transform (f, indent, dest, true, 1, optype, e->ops[j]->gen_transform (f, indent, dest, true, 1, optype,
&cinfo, &cinfo, indexes, cond_handling);
indexes, expand_generic_cond_exprs_p);
} }
/* Re-fold the toplevel result. It's basically an embedded /* 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) ...@@ -3068,7 +3072,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result)
|| result->type == operand::OP_C_EXPR) || result->type == operand::OP_C_EXPR)
{ {
result->gen_transform (f, indent, "res_ops[0]", true, 1, "type", 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"); fprintf_indent (f, indent, "*res_code = TREE_CODE (res_ops[0]);\n");
if (is_a <capture *> (result) if (is_a <capture *> (result)
&& cinfo.info[as_a <capture *> (result)->where].cond_expr_cond_p) && cinfo.info[as_a <capture *> (result)->where].cond_expr_cond_p)
......
...@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h" #include "tree-pass.h"
#include "internal-fn.h" #include "internal-fn.h"
#include "case-cfn-macros.h" #include "case-cfn-macros.h"
#include "gimplify.h"
/* Forward declarations of the private auto-generated matchers. /* Forward declarations of the private auto-generated matchers.
......
...@@ -1752,28 +1752,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -1752,28 +1752,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cnd (logical_inverted_value truth_valued_p@0) @1 @2) (cnd (logical_inverted_value truth_valued_p@0) @1 @2)
(cnd @0 @2 @1))) (cnd @0 @2 @1)))
/* A + (B vcmp C ? 1 : 0) -> A - (B vcmp C), since vector comparisons /* A + (B vcmp C ? 1 : 0) -> A - (B vcmp C ? -1 : 0), since vector comparisons
return all-1 or all-0 results. */ return all -1 or all 0 results. */
/* ??? We could instead convert all instances of the vec_cond to negate, /* ??? We could instead convert all instances of the vec_cond to negate,
but that isn't necessarily a win on its own. */ but that isn't necessarily a win on its own. */
(simplify (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) (if (VECTOR_TYPE_P (type)
&& VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (@0)))
&& TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0)) && TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0))
&& (TYPE_MODE (TREE_TYPE (type)) && (TYPE_MODE (TREE_TYPE (type))
== TYPE_MODE (TREE_TYPE (TREE_TYPE (@0))))) == 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 (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) (if (VECTOR_TYPE_P (type)
&& VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (@0)))
&& TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0)) && TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0))
&& (TYPE_MODE (TREE_TYPE (type)) && (TYPE_MODE (TREE_TYPE (type))
== TYPE_MODE (TREE_TYPE (TREE_TYPE (@0))))) == 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. */ /* Simplifications of comparisons. */
......
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> 2016-03-22 David Malcolm <dmalcolm@redhat.com>
PR c/69993 PR c/69993
......
// { 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment