This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][match-and-simplify] Fix type guessing for conversions
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 27 Aug 2014 14:04:47 +0200 (CEST)
- Subject: [PATCH][match-and-simplify] Fix type guessing for conversions
- Authentication-results: sourceware.org; auth=none
The following fixes type guessing by handling VIEW_CONVERT_EXPR
and by properly passing down "unknown" for outermost conversions.
Btw, a case where we need some explicit type specification support
is Convert (T1)(X * Y) into (T1)X * (T1)Y which needs to eventually
use an unsigned type for the multiplication. Suggested syntax
could be
/* Convert (T1)(X * Y) into (T1)X * (T1)Y if T1 is narrower than the
type of X and Y (integer types only). */
(simplify
(convert (mult @0 @1))
(if (INTEGRAL_TYPE_P (type)
&& INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@0)))
(if (TYPE_OVERFLOW_WRAPS (type))
(mult (convert @0) (convert @1)))
/* 1) We can't handle the two-conversions-in-a-row below.
2) We can't properly specify the type for the inner conversion
(unsigned_type_for). Suggested syntax below. */
(with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
(convert (mult (convert:utype @0) (convert:utype @1))))))
Committed.
Richard.
2014-08-27 Richard Biener <rguenther@suse.de>
* genmatch.c (is_conversion): New helper, add VIEW_CONVERT_EXPR
to the list of conversions.
(expr::gen_transform): Use it.
(dt_simplify::gen): Properly pass down NULL as the operand
type for outermost conversions.
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c (revision 214568)
+++ gcc/genmatch.c (working copy)
@@ -866,22 +866,27 @@ check_no_user_id (simplify *s)
check_no_user_id (s->result);
}
+bool
+is_conversion (id_base *op)
+{
+ return (*op == CONVERT_EXPR
+ || *op == NOP_EXPR
+ || *op == FLOAT_EXPR
+ || *op == FIX_TRUNC_EXPR
+ || *op == VIEW_CONVERT_EXPR);
+}
+
/* Code gen off the AST. */
void
expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
const char *in_type)
{
- bool is_conversion = false;
- if (*operation->op == CONVERT_EXPR
- || *operation->op == NOP_EXPR
- || *operation->op == FLOAT_EXPR
- || *operation->op == FIX_TRUNC_EXPR)
- is_conversion = true;
+ bool conversion_p = is_conversion (operation->op);
const char *type;
char optype[20];
- if (is_conversion)
+ if (conversion_p)
/* For conversions we need to build the expression using the
outer type passed in. */
type = in_type;
@@ -901,7 +906,7 @@ expr::gen_transform (FILE *f, const char
char dest[32];
snprintf (dest, 32, " ops%d[%u]", depth, i);
ops[i]->gen_transform (f, dest, gimple, depth + 1,
- is_conversion
+ conversion_p
/* If this op is a conversion its single
operand has to know its type itself. */
? NULL
@@ -1769,7 +1774,9 @@ dt_simplify::gen (FILE *f, bool gimple)
{
char dest[32];
snprintf (dest, 32, " res_ops[%d]", j);
- e->ops[j]->gen_transform (f, dest, true, 1, "type");
+ e->ops[j]->gen_transform (f, dest, true, 1,
+ is_conversion (e->operation->op)
+ ? NULL : "type");
}
/* Re-fold the toplevel result. It's basically an embedded
gimple_build w/o actually building the stmt. */
@@ -1796,7 +1803,9 @@ dt_simplify::gen (FILE *f, bool gimple)
fprintf (f, " tree res_op%d;\n", j);
char dest[32];
snprintf (dest, 32, " res_op%d", j);
- e->ops[j]->gen_transform (f, dest, false, 1, "type");
+ e->ops[j]->gen_transform (f, dest, false, 1,
+ is_conversion (e->operation->op)
+ ? NULL : "type");
}
/* Re-fold the toplevel result. */
if (e->operation->op->kind == id_base::CODE)