+2015-07-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/66948
+ * genmatch.c (capture_info::walk_match): Also recurse to
+ captures. Properly compute expr state from captures of
+ captures.
+ * match.pd: Add single-use guards to
+ (X & C2) >> C1 into (X >> C1) & (C2 >> C1) transform.
+
2015-07-21 Nathan Sidwell <nathan@codesourcery.com>
* config/nvptx/mkoffload.c (process): Add static destructor call.
{
if (capture *c = dyn_cast <capture *> (o))
{
- info[c->where].toplevel_msk |= 1 << toplevel_arg;
- info[c->where].force_no_side_effects_p |= conditional_p;
- info[c->where].cond_expr_cond_p |= cond_expr_cond_p;
- /* Mark expr (non-leaf) captures and recurse. */
+ unsigned where = c->where;
+ info[where].toplevel_msk |= 1 << toplevel_arg;
+ info[where].force_no_side_effects_p |= conditional_p;
+ info[where].cond_expr_cond_p |= cond_expr_cond_p;
+ if (!c->what)
+ return;
+ /* Recurse to exprs and captures. */
+ if (is_a <capture *> (c->what)
+ || is_a <expr *> (c->what))
+ walk_match (c->what, toplevel_arg, conditional_p, false);
+ /* We need to look past multiple captures to find a captured
+ expression as with conditional converts two captures
+ can be collapsed onto the same expression. */
+ while (c->what && is_a <capture *> (c->what))
+ c = as_a <capture *> (c->what);
+ /* Mark expr (non-leaf) captures and forced single-use exprs. */
expr *e;
if (c->what
&& (e = dyn_cast <expr *> (c->what)))
{
- info[c->where].expr_p = true;
- info[c->where].force_single_use |= e->force_single_use;
- walk_match (c->what, toplevel_arg, conditional_p, false);
+ info[where].expr_p = true;
+ info[where].force_single_use |= e->force_single_use;
}
}
else if (expr *e = dyn_cast <expr *> (o))
(X & C2) >> C1 into (X >> C1) & (C2 >> C1). */
(for shift (lshift rshift)
(simplify
- (shift (convert? (bit_and @0 INTEGER_CST@2)) INTEGER_CST@1)
+ (shift (convert?:s (bit_and:s @0 INTEGER_CST@2)) INTEGER_CST@1)
(if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
(with { tree mask = int_const_binop (shift, fold_convert (type, @2), @1); }
(bit_and (shift (convert @0) @1) { mask; })))))