The following patch fixes a subtle issue with how (if ...) is currently
operating.  Take

/* Transform comparisons of the form X * C1 CMP 0 to X CMP 0 in the
   signed arithmetic case.  That form is created by the compiler
   often enough for folding it to be of value.  One example is in
   computing loop trip counts after Operator Strength Reduction.  */
(for cmp (simple_comparison)
     scmp (swapped_simple_comparison)
 (simplify
  (cmp (mult @0 INTEGER_CST@1) integer_zerop@2)
  /* Handle unfolded multiplication by zero.  */
  (if (integer_zerop (@1))
   (cmp @1 @2))
  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
   /* If @1 is negative we swap the sense of the comparison.  */
   (if (tree_int_cst_sgn (@1) < 0)
    (scmp @0 @2))
   (cmp @0 @2))))

as an example.  Currently there is no "else" arm implemented
because of an implementation detail.  That implementation detail
is that currently the above is equivalent to three separate
simplify patterns, each collecting 'if's from their final result
expression.  Thus,

  (if (integer_zerop (@1))
   (cmp @1 @2))

  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
   /* If @1 is negative we swap the sense of the comparison.  */
   (if (tree_int_cst_sgn (@1) < 0)
    (scmp @0 @2))

and

  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
   (cmp @0 @2))))

and the fact that the last one is "mostly" equivalent to

  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
   (if (!(tree_int_cst_sgn (@1) < 0))
    (cmp @0 @2))))

is just because the first one is guaranteed to match first - _if_ it
matches.  Matching can fail due to various reasons though and it
is not always obvious whether the fallthru is really equivalent to
an else.

Lack of an explicit else was also pointed out as a missing feature.
The following patch fixes the above implementation detail and keeps
a single 'simplify' for the whole if/with expression tree (thus
also not duplicating common ifs and withs).  It adds an explicit
else and removes the ability to "sequence" stuff via the fallthru.

Thus the above pattern now becomes

/* Transform comparisons of the form X * C1 CMP 0 to X CMP 0 in the
   signed arithmetic case.  That form is created by the compiler
   often enough for folding it to be of value.  One example is in
   computing loop trip counts after Operator Strength Reduction.  */
(for cmp (simple_comparison)
     scmp (swapped_simple_comparison)
 (simplify
  (cmp (mult @0 INTEGER_CST@1) integer_zerop@2)
  /* Handle unfolded multiplication by zero.  */
  (if (integer_zerop (@1))
   (cmp @1 @2)
   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
        && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
    /* If @1 is negative we swap the sense of the comparison.  */
    (if (tree_int_cst_sgn (@1) < 0)
     (scmp @0 @2)
     (cmp @0 @2))))))

as the new if syntax is

 (if (cond-expr)
   (then-expr)
  [(else-expr)])

with the else-expr being optional.  Note that writing

 (if (cond1)
  (bla))
 (if (cond2)
  (foo))
 (if (cond3)
  (baz))

is no longer supported (I might introduce that again as followup
with explicitely denoting this as 'switch/case' list).

This means touching quite a few patterns in match.pd.  Most cases
simply didn't continue parsing but the following one for example
has different meaning before and after:

 (if (cond1)
  (if (cond2)
   (expr1))
  (expr2))

now expr2 is guarded by !cond1 while formerly it was guarded by cond1.

Anticipating 'switch/case' support I have not re-indented the cases
of large (if ..) (else if ...) (else if ...) forms.

As this now keeps the if/with expression tree doing further
simplifications to make the generated code smaller should now
be easier.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2015-07-13  Richard Biener  <rguent...@suse.de>

        * genmatch.c (struct operand): Add OP_IF and OP_WITH op_types.
        (struct if_expr): New.
        (struct with_expr): Likewise.
        (is_a_helper): Add helpers for if_expr and with_expr.
        (struct simplify): Add simplify_kind enum and member.  Remove
        ifexpr_vec member.
        (simplify::simplify): Adjust.
        (lower_commutative): Adjust.
        (lower_opt_convert): Likewise.
        (lower_cond): Likewise.
        (replace_id): Handle with_expr and if_expr.
        (lower_for): Adjust.
        (dt_simplify::gen_1): New recursive worker, split out from ...
        (dt_simplify::gen): ... here.  Deal with if and with expansion
        recursively.
        (capture_info::capture_info): Take context argument
        (capture_info::walk_result): Only analyze specific result.
        (parser::parse_result): New function.
        (parser::parse_simplify): Adjust to parse ifs with then end
        else case.
        (parser::parse_if): Simplify.
        (parser::parse_pattern): Pass down simplify kind.
        * match.pd: Convert if structure to new syntax.

Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c      (revision 225727)
+++ gcc/genmatch.c      (working copy)
@@ -482,7 +482,7 @@ struct capture_info;
 /* The base class for operands.  */
 
 struct operand {
-  enum op_type { OP_PREDICATE, OP_EXPR, OP_CAPTURE, OP_C_EXPR };
+  enum op_type { OP_PREDICATE, OP_EXPR, OP_CAPTURE, OP_C_EXPR, OP_IF, OP_WITH 
};
   operand (enum op_type type_) : type (type_) {}
   enum op_type type;
   virtual void gen_transform (FILE *, int, const char *, bool, int,
@@ -578,6 +578,26 @@ struct capture : public operand
                              dt_operand ** = 0, bool = true);
 };
 
+/* if expression.  */
+
+struct if_expr : public operand
+{
+  if_expr () : operand (OP_IF), cond (NULL), trueexpr (NULL),
+    falseexpr (NULL) {}
+  c_expr *cond;
+  operand *trueexpr;
+  operand *falseexpr;
+};
+
+/* with expression.  */
+
+struct with_expr : public operand
+{
+  with_expr () : operand (OP_WITH), with (NULL), subexpr (NULL) {}
+  c_expr *with;
+  operand *subexpr;
+};
+
 template<>
 template<>
 inline bool
@@ -610,16 +630,21 @@ is_a_helper <expr *>::test (operand *op)
   return op->type == operand::OP_EXPR;
 }
 
-/* Helper to distinguish 'if' from 'with' expressions.  */
+template<>
+template<>
+inline bool
+is_a_helper <if_expr *>::test (operand *op)
+{
+  return op->type == operand::OP_IF;
+}
 
-struct if_or_with
+template<>
+template<>
+inline bool
+is_a_helper <with_expr *>::test (operand *op)
 {
-  if_or_with (operand *cexpr_, source_location location_, bool is_with_)
-      : location (location_), cexpr (cexpr_), is_with (is_with_) {}
-  source_location location;
-  operand *cexpr;
-  bool is_with;
-};
+  return op->type == operand::OP_WITH;
+}
 
 /* The main class of a pattern and its transform.  This is used to
    represent both (simplify ...) and (match ...) kinds.  The AST
@@ -628,26 +653,27 @@ struct if_or_with
 
 struct simplify
 {
-  simplify (operand *match_, source_location match_location_,
+  enum simplify_kind { SIMPLIFY, MATCH };
+
+  simplify (simplify_kind kind_,
+           operand *match_, source_location match_location_,
            struct operand *result_, source_location result_location_,
-           vec<if_or_with> ifexpr_vec_, vec<vec<user_id *> > for_vec_,
-           cid_map_t *capture_ids_)
-      : match (match_), match_location (match_location_),
+           vec<vec<user_id *> > for_vec_, cid_map_t *capture_ids_)
+      : kind (kind_), match (match_), match_location (match_location_),
       result (result_), result_location (result_location_),
-      ifexpr_vec (ifexpr_vec_), for_vec (for_vec_),
+      for_vec (for_vec_),
       capture_ids (capture_ids_), capture_max (capture_ids_->elements () - 1) 
{}
 
+  simplify_kind kind;
   /* The expression that is matched against the GENERIC or GIMPLE IL.  */
   operand *match;
   source_location match_location;
-  /* For a (simplify ...) the expression produced when the pattern applies.
-     For a (match ...) either NULL if it is a simple predicate or the
-     single expression specifying the matched operands.  */
+  /* For a (simplify ...) an expression with ifs and withs with the expression
+     produced when the pattern applies in the leafs.
+     For a (match ...) the leafs are either empty if it is a simple predicate
+     or the single expression specifying the matched operands.  */
   struct operand *result;
   source_location result_location;
-  /* Collected 'if' expressions that need to evaluate to true to make
-     the pattern apply.  */
-  vec<if_or_with> ifexpr_vec;
   /* Collected 'for' expression operators that have to be replaced
      in the lowering phase.  */
   vec<vec<user_id *> > for_vec;
@@ -803,8 +829,8 @@ lower_commutative (simplify *s, vec<simp
   vec<operand *> matchers = commutate (s->match);
   for (unsigned i = 0; i < matchers.length (); ++i)
     {
-      simplify *ns = new simplify (matchers[i], s->match_location,
-                                  s->result, s->result_location, s->ifexpr_vec,
+      simplify *ns = new simplify (s->kind, matchers[i], s->match_location,
+                                  s->result, s->result_location,
                                   s->for_vec, s->capture_ids);
       simplifiers.safe_push (ns);
     }
@@ -932,8 +958,8 @@ lower_opt_convert (simplify *s, vec<simp
   vec<operand *> matchers = lower_opt_convert (s->match);
   for (unsigned i = 0; i < matchers.length (); ++i)
     {
-      simplify *ns = new simplify (matchers[i], s->match_location,
-                                  s->result, s->result_location, s->ifexpr_vec,
+      simplify *ns = new simplify (s->kind, matchers[i], s->match_location,
+                                  s->result, s->result_location,
                                   s->for_vec, s->capture_ids);
       simplifiers.safe_push (ns);
     }
@@ -1032,8 +1058,8 @@ lower_cond (simplify *s, vec<simplify *>
   vec<operand *> matchers = lower_cond (s->match);
   for (unsigned i = 0; i < matchers.length (); ++i)
     {
-      simplify *ns = new simplify (matchers[i], s->match_location,
-                                  s->result, s->result_location, s->ifexpr_vec,
+      simplify *ns = new simplify (s->kind, matchers[i], s->match_location,
+                                  s->result, s->result_location,
                                   s->for_vec, s->capture_ids);
       simplifiers.safe_push (ns);
     }
@@ -1061,6 +1087,22 @@ replace_id (operand *o, user_id *id, id_
        ne->append_op (replace_id (e->ops[i], id, with));
       return ne;
     }
+  else if (with_expr *w = dyn_cast <with_expr *> (o))
+    {
+      with_expr *nw = new with_expr ();
+      nw->with = as_a <c_expr *> (replace_id (w->with, id, with));
+      nw->subexpr = replace_id (w->subexpr, id, with);
+      return nw;
+    }
+  else if (if_expr *ife = dyn_cast <if_expr *> (o))
+    {
+      if_expr *nife = new if_expr ();
+      nife->cond = as_a <c_expr *> (replace_id (ife->cond, id, with));
+      nife->trueexpr = replace_id (ife->trueexpr, id, with);
+      if (ife->falseexpr)
+       nife->falseexpr = replace_id (ife->falseexpr, id, with);
+      return nife;
+    }
 
   /* For c_expr we simply record a string replacement table which is
      applied at code-generation time.  */
@@ -1105,8 +1147,6 @@ lower_for (simplify *sin, vec<simplify *
            {
              operand *match_op = s->match;
              operand *result_op = s->result;
-             vec<if_or_with> ifexpr_vec = s->ifexpr_vec.copy ();
-
              for (unsigned i = 0; i < n_ids; ++i)
                {
                  user_id *id = ids[i];
@@ -1114,13 +1154,10 @@ lower_for (simplify *sin, vec<simplify *
                  match_op = replace_id (match_op, id, oper);
                  if (result_op)
                    result_op = replace_id (result_op, id, oper);
-                 for (unsigned k = 0; k < s->ifexpr_vec.length (); ++k)
-                   ifexpr_vec[k].cexpr = replace_id (ifexpr_vec[k].cexpr,
-                                                     id, oper);
                }
-             simplify *ns = new simplify (match_op, s->match_location,
+             simplify *ns = new simplify (s->kind, match_op, s->match_location,
                                           result_op, s->result_location,
-                                          ifexpr_vec, vNULL, s->capture_ids);
+                                          vNULL, s->capture_ids);
              worklist.safe_push (ns);
            }
        }
@@ -1228,6 +1265,7 @@ struct dt_simplify : public dt_node
        : dt_node (DT_SIMPLIFY), s (s_), pattern_no (pattern_no_),
          indexes (indexes_)  {}
 
+  void gen_1 (FILE *, int, bool, operand *);
   void gen (FILE *f, int, bool);
 };
 
@@ -1530,9 +1568,9 @@ decision_tree::print (FILE *f)
 
 struct capture_info
 {
-  capture_info (simplify *s);
+  capture_info (simplify *s, operand *);
   void walk_match (operand *o, unsigned toplevel_arg, bool, bool);
-  void walk_result (operand *o, bool);
+  bool walk_result (operand *o, bool, operand *);
   void walk_c_expr (c_expr *);
 
   struct cinfo
@@ -1552,12 +1590,10 @@ struct capture_info
 
 /* Analyze captures in S.  */
 
-capture_info::capture_info (simplify *s)
+capture_info::capture_info (simplify *s, operand *result)
 {
   expr *e;
-  if (!s->result
-      || ((e = dyn_cast <expr *> (s->result))
-         && is_a <predicate_id *> (e->operation)))
+  if (s->kind == simplify::MATCH)
     {
       force_no_side_effects = -1;
       return;
@@ -1575,11 +1611,7 @@ capture_info::capture_info (simplify *s)
                && (*e->operation == COND_EXPR
                    || *e->operation == VEC_COND_EXPR));
 
-  walk_result (s->result, false);
-
-  for (unsigned i = 0; i < s->ifexpr_vec.length (); ++i)
-    if (s->ifexpr_vec[i].is_with)
-      walk_c_expr (as_a <c_expr *>(s->ifexpr_vec[i].cexpr));
+  walk_result (s->result, false, result);
 }
 
 /* Analyze captures in the match expression piece O.  */
@@ -1630,10 +1662,12 @@ capture_info::walk_match (operand *o, un
     gcc_unreachable ();
 }
 
-/* Analyze captures in the result expression piece O.  */
+/* Analyze captures in the result expression piece O.  Return true
+   if RESULT was visited in one of the children.  Only visit
+   non-if/with children if they are rooted on RESULT.  */
 
-void
-capture_info::walk_result (operand *o, bool conditional_p)
+bool
+capture_info::walk_result (operand *o, bool conditional_p, operand *result)
 {
   if (capture *c = dyn_cast <capture *> (o))
     {
@@ -1650,7 +1684,7 @@ capture_info::walk_result (operand *o, b
          && is_a <expr *> (c->what))
        {
          info[c->where].cse_p = true;
-         walk_result (c->what, true);
+         walk_result (c->what, true, result);
        }
     }
   else if (expr *e = dyn_cast <expr *> (o))
@@ -1663,13 +1697,49 @@ capture_info::walk_result (operand *o, b
          else if (*e->operation == TRUTH_ANDIF_EXPR
                   || *e->operation == TRUTH_ORIF_EXPR)
            cond_p = true;
-         walk_result (e->ops[i], cond_p);
+         walk_result (e->ops[i], cond_p, result);
        }
     }
+  else if (if_expr *e = dyn_cast <if_expr *> (o))
+    {
+      /* 'if' conditions should be all fine.  */
+      if (e->trueexpr == result)
+       {
+         walk_result (e->trueexpr, false, result);
+         return true;
+       }
+      if (e->falseexpr == result)
+       {
+         walk_result (e->falseexpr, false, result);
+         return true;
+       }
+      bool res = false;
+      if (is_a <if_expr *> (e->trueexpr)
+         || is_a <with_expr *> (e->trueexpr))
+       res |= walk_result (e->trueexpr, false, result);
+      if (e->falseexpr
+         && (is_a <if_expr *> (e->falseexpr)
+             || is_a <with_expr *> (e->falseexpr)))
+       res |= walk_result (e->falseexpr, false, result);
+      return res;
+    }
+  else if (with_expr *e = dyn_cast <with_expr *> (o))
+    {
+      bool res = (e->subexpr == result);
+      if (res
+         || is_a <if_expr *> (e->subexpr)
+         || is_a <with_expr *> (e->subexpr))
+       res |= walk_result (e->subexpr, false, result);
+      if (res)
+       walk_c_expr (e->with);
+      return res;
+    }
   else if (c_expr *e = dyn_cast <c_expr *> (o))
     walk_c_expr (e);
   else
     gcc_unreachable ();
+
+  return false;
 }
 
 /* Look for captures in the C expr E.  */
@@ -2487,87 +2557,55 @@ dt_operand::gen (FILE *f, int indent, bo
 }
 
 
-
 /* Generate code for the '(if ...)', '(with ..)' and actual transform
    step of a '(simplify ...)' or '(match ...)'.  This handles everything
-   that is not part of the decision tree (simplify->match).  */
+   that is not part of the decision tree (simplify->match).
+   Main recursive worker.  */
 
 void
-dt_simplify::gen (FILE *f, int indent, bool gimple)
+dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result)
 {
-  fprintf_indent (f, indent, "{\n");
-  indent += 2;
-  output_line_directive (f, s->result_location);
-  if (s->capture_max >= 0)
-    fprintf_indent (f, indent, "tree captures[%u] ATTRIBUTE_UNUSED = {};\n",
-                   s->capture_max + 1);
-
-  for (int i = 0; i <= s->capture_max; ++i)
-    if (indexes[i])
-      {
-       char opname[20];
-       fprintf_indent (f, indent, "captures[%u] = %s;\n",
-                       i, indexes[i]->get_name (opname));
-      }
-
-  unsigned n_braces = 0;
-  if (s->ifexpr_vec != vNULL)
+  if (result)
     {
-      for (unsigned i = 0; i < s->ifexpr_vec.length (); ++i)
+      if (with_expr *w = dyn_cast <with_expr *> (result))
+       {
+         fprintf_indent (f, indent, "{\n");
+         indent += 4;
+         output_line_directive (f, w->with->code[0].src_loc);
+         w->with->gen_transform (f, indent, NULL, true, 1, "type", NULL);
+         gen_1 (f, indent, gimple, w->subexpr);
+         indent -= 4;
+         fprintf_indent (f, indent, "}\n");
+         return;
+       }
+      else if (if_expr *ife = dyn_cast <if_expr *> (result))
        {
-         if_or_with &w = s->ifexpr_vec[i];
-         if (w.is_with)
+         output_line_directive (f, ife->cond->code[0].src_loc);
+         fprintf_indent (f, indent, "if (");
+         ife->cond->gen_transform (f, indent, NULL, true, 1, "type", NULL);
+         fprintf (f, ")\n");
+         fprintf_indent (f, indent + 2, "{\n");
+         indent += 4;
+         gen_1 (f, indent, gimple, ife->trueexpr);
+         indent -= 4;
+         fprintf_indent (f, indent + 2, "}\n");
+         if (ife->falseexpr)
            {
-             fprintf_indent (f, indent, "{\n");
+             fprintf_indent (f, indent, "else\n");
+             fprintf_indent (f, indent + 2, "{\n");
              indent += 4;
-             output_line_directive (f, w.location);
-             w.cexpr->gen_transform (f, indent, NULL, true, 1, "type", NULL);
-             n_braces++;
-           }
-         else
-           {
-             output_line_directive (f, w.location);
-             fprintf_indent (f, indent, "if (");
-             if (i == s->ifexpr_vec.length () - 1
-                 || s->ifexpr_vec[i+1].is_with)
-               w.cexpr->gen_transform (f, indent, NULL, true, 1, "type", NULL);
-             else
-               {
-                 unsigned j = i;
-                 do
-                   {
-                     if (j != i)
-                       {
-                         fprintf (f, "\n");
-                         output_line_directive (f, s->ifexpr_vec[j].location);
-                         fprintf_indent (f, indent + 4, "&& ");
-                       }
-                     fprintf (f, "(");
-                     s->ifexpr_vec[j].cexpr->gen_transform (f, 0, NULL,
-                                                            true, 1, "type",
-                                                            NULL);
-                     fprintf (f, ")");
-                     ++j;
-                   }
-                 while (j < s->ifexpr_vec.length ()
-                        && !s->ifexpr_vec[j].is_with);
-                 i = j - 1;
-               }
-             fprintf (f, ")\n");
+             gen_1 (f, indent, gimple, ife->falseexpr);
+             indent -= 4;
+             fprintf_indent (f, indent + 2, "}\n");
            }
+         return;
        }
-      fprintf_indent (f, indent + 2, "{\n");
-      indent += 4;
-      n_braces++;
     }
 
   /* Analyze captures and perform early-outs on the incoming arguments
      that cover cases we cannot handle.  */
-  capture_info cinfo (s);
-  expr *e;
-  if (s->result
-      && !((e = dyn_cast <expr *> (s->result))
-          && is_a <predicate_id *> (e->operation)))
+  capture_info cinfo (s, result);
+  if (s->kind == simplify::SIMPLIFY)
     {
       if (!gimple)
        {
@@ -2626,7 +2664,6 @@ dt_simplify::gen (FILE *f, int indent, b
   output_line_directive (f, s->result_location, true);
   fprintf (f, ", %%s:%%d\\n\", __FILE__, __LINE__);\n");
 
-  operand *result = s->result;
   if (!result)
     {
       /* If there is no result then this is a predicate implementation.  */
@@ -2782,7 +2819,7 @@ dt_simplify::gen (FILE *f, int indent, b
 
        {
          fprintf_indent (f, indent, "tree res;\n");
-         s->result->gen_transform (f, indent, "res", false, 1, "type",
+         result->gen_transform (f, indent, "res", false, 1, "type",
                                    &cinfo, indexes);
        }
       else
@@ -2809,12 +2846,31 @@ dt_simplify::gen (FILE *f, int indent, b
          fprintf_indent (f, indent, "return res;\n");
        }
     }
+}
 
-  for (unsigned i = 0; i < n_braces; ++i)
-    {
-      fprintf_indent (f, indent - 2, "}\n");
-      indent -= 4;
-    }
+/* Generate code for the '(if ...)', '(with ..)' and actual transform
+   step of a '(simplify ...)' or '(match ...)'.  This handles everything
+   that is not part of the decision tree (simplify->match).  */
+
+void
+dt_simplify::gen (FILE *f, int indent, bool gimple)
+{
+  fprintf_indent (f, indent, "{\n");
+  indent += 2;
+  output_line_directive (f, s->result_location);
+  if (s->capture_max >= 0)
+    fprintf_indent (f, indent, "tree captures[%u] ATTRIBUTE_UNUSED = {};\n",
+                   s->capture_max + 1);
+
+  for (int i = 0; i <= s->capture_max; ++i)
+    if (indexes[i])
+      {
+       char opname[20];
+       fprintf_indent (f, indent, "captures[%u] = %s;\n",
+                       i, indexes[i]->get_name (opname));
+      }
+
+  gen_1 (f, indent, gimple, s->result);
 
   indent -= 2;
   fprintf_indent (f, indent, "}\n");
@@ -2976,17 +3032,20 @@ private:
   void record_operlist (source_location, user_id *);
 
   void parse_pattern ();
-  void push_simplify (vec<simplify *>&, operand *, source_location,
+  operand *parse_result (operand *, predicate_id *);
+  void push_simplify (simplify::simplify_kind,
+                     vec<simplify *>&, operand *, source_location,
                      operand *, source_location);
-  void parse_simplify (source_location, vec<simplify *>&, predicate_id *,
-                      expr *);
+  void parse_simplify (simplify::simplify_kind,
+                      source_location, vec<simplify *>&, predicate_id *,
+                      operand *);
   void parse_for (source_location);
   void parse_if (source_location);
   void parse_predicates (source_location);
   void parse_operator_list (source_location);
 
   cpp_reader *r;
-  vec<if_or_with> active_ifs;
+  vec<c_expr *> active_ifs;
   vec<vec<user_id *> > active_fors;
   hash_set<user_id *> *oper_lists_set;
   vec<user_id *> oper_lists;
@@ -3425,7 +3484,8 @@ parser::parse_op ()
    MATCH_LOC, RESULT and RESULT_LOC and push it to SIMPLIFIERS.  */
 
 void
-parser::push_simplify (vec<simplify *>& simplifiers,
+parser::push_simplify (simplify::simplify_kind kind,
+                      vec<simplify *>& simplifiers,
                       operand *match, source_location match_loc,
                       operand *result, source_location result_loc)
 {
@@ -3434,27 +3494,90 @@ parser::push_simplify (vec<simplify *>&
     active_fors.safe_push (oper_lists);
 
   simplifiers.safe_push
-    (new simplify (match, match_loc, result, result_loc,
-                  active_ifs.copy (), active_fors.copy (), capture_ids));
+    (new simplify (kind, match, match_loc, result, result_loc,
+                  active_fors.copy (), capture_ids));
 
   if (!oper_lists.is_empty ())
     active_fors.pop ();
 }
 
 /* Parse
-     simplify = 'simplify' <expr> <result-op>
-   or
-     match = 'match' <ident> <expr> [<result-op>]
-   with
      <result-op> = <op> | <if> | <with>
      <if> = '(' 'if' '(' <c-expr> ')' <result-op> ')'
      <with> = '(' 'with' '{' <c-expr> '}' <result-op> ')'
+   and return it.  */
+
+operand *
+parser::parse_result (operand *result, predicate_id *matcher)
+{
+  const cpp_token *token = peek ();
+  if (token->type != CPP_OPEN_PAREN)
+    return parse_op ();
+
+  eat_token (CPP_OPEN_PAREN);
+  if (peek_ident ("if"))
+    {
+      eat_ident ("if");
+      if_expr *ife = new if_expr ();
+      ife->cond = parse_c_expr (CPP_OPEN_PAREN);
+      if (peek ()->type == CPP_OPEN_PAREN)
+       {
+         ife->trueexpr = parse_result (result, matcher);
+         if (peek ()->type == CPP_OPEN_PAREN)
+           ife->falseexpr = parse_result (result, matcher);
+         else if (peek ()->type != CPP_CLOSE_PAREN)
+           ife->falseexpr = parse_op ();
+       }
+      else if (peek ()->type != CPP_CLOSE_PAREN)
+       {
+         ife->trueexpr = parse_op ();
+         if (peek ()->type == CPP_OPEN_PAREN)
+           ife->falseexpr = parse_result (result, matcher);
+         else if (peek ()->type != CPP_CLOSE_PAREN)
+           ife->falseexpr = parse_op ();
+       }
+      /* If this if is immediately closed then it contains a
+        manual matcher or is part of a predicate definition.  */
+      else /* if (peek ()->type == CPP_CLOSE_PAREN) */
+       {
+         if (!matcher)
+           fatal_at (peek (), "manual transform not implemented");
+       }
+      eat_token (CPP_CLOSE_PAREN);
+      return ife;
+    }
+  else if (peek_ident ("with"))
+    {
+      eat_ident ("with");
+      with_expr *withe = new with_expr ();
+      /* Parse (with c-expr expr) as (if-with (true) expr).  */
+      withe->with = parse_c_expr (CPP_OPEN_BRACE);
+      withe->with->nr_stmts = 0;
+      withe->subexpr = parse_result (result, matcher);
+      eat_token (CPP_CLOSE_PAREN);
+      return withe;
+    }
+  else
+    {
+      operand *op = result;
+      if (!matcher)
+       op = parse_expr ();
+      eat_token (CPP_CLOSE_PAREN);
+      return op;
+    }
+}
+
+/* Parse
+     simplify = 'simplify' <expr> <result-op>
+   or
+     match = 'match' <ident> <expr> [<result-op>]
    and fill SIMPLIFIERS with the results.  */
 
 void
-parser::parse_simplify (source_location match_location,
+parser::parse_simplify (simplify::simplify_kind kind,
+                       source_location match_location,
                        vec<simplify *>& simplifiers, predicate_id *matcher,
-                       expr *result)
+                       operand *result)
 {
   /* Reset the capture map.  */
   if (!capture_ids)
@@ -3474,6 +3597,20 @@ parser::parse_simplify (source_location
       && is_a <predicate_id *> (as_a <expr *> (match)->operation))
     fatal_at (loc, "outermost expression cannot be a predicate");
 
+  /* Splice active_ifs onto result and continue parsing the
+     "then" expr.  */
+  if_expr *active_if = NULL;
+  for (int i = active_ifs.length (); i > 0; --i)
+    {
+      if_expr *ifc = new if_expr ();
+      ifc->cond = active_ifs[i-1];
+      ifc->trueexpr = active_if;
+      active_if = ifc;
+    }
+  if_expr *outermost_if = active_if;
+  while (active_if && active_if->trueexpr)
+    active_if = as_a <if_expr *> (active_if->trueexpr);
+
   const cpp_token *token = peek ();
 
   /* If this if is immediately closed then it is part of a predicate
@@ -3482,89 +3619,27 @@ parser::parse_simplify (source_location
     {
       if (!matcher)
        fatal_at (token, "expected transform expression");
-      push_simplify (simplifiers, match, match_location,
+      if (active_if)
+       {
+         active_if->trueexpr = result;
+         result = outermost_if;
+       }
+      push_simplify (kind, simplifiers, match, match_location,
                     result, token->src_loc);
       return;
     }
 
-  unsigned active_ifs_len = active_ifs.length ();
-  while (1)
+  operand *tem = parse_result (result, matcher);
+  if (active_if)
     {
-      if (token->type == CPP_OPEN_PAREN)
-       {
-         source_location paren_loc = token->src_loc;
-         eat_token (CPP_OPEN_PAREN);
-         if (peek_ident ("if"))
-           {
-             eat_ident ("if");
-             active_ifs.safe_push (if_or_with (parse_c_expr (CPP_OPEN_PAREN),
-                                               token->src_loc, false));
-             /* If this if is immediately closed then it contains a
-                manual matcher or is part of a predicate definition.
-                Push it.  */
-             if (peek ()->type == CPP_CLOSE_PAREN)
-               {
-                 if (!matcher)
-                   fatal_at (token, "manual transform not implemented");
-                 push_simplify (simplifiers, match, match_location,
-                                result, paren_loc);
-               }
-           }
-         else if (peek_ident ("with"))
-           {
-             eat_ident ("with");
-             /* Parse (with c-expr expr) as (if-with (true) expr).  */
-             c_expr *e = parse_c_expr (CPP_OPEN_BRACE);
-             e->nr_stmts = 0;
-             active_ifs.safe_push (if_or_with (e, token->src_loc, true));
-           }
-         else
-           {
-             operand *op = result;
-             if (!matcher)
-               op = parse_expr ();
-             push_simplify (simplifiers, match, match_location,
-                            op, token->src_loc);
-             eat_token (CPP_CLOSE_PAREN);
-             /* A "default" result closes the enclosing scope.  */
-             if (active_ifs.length () > active_ifs_len)
-               {
-                 eat_token (CPP_CLOSE_PAREN);
-                 active_ifs.pop ();
-               }
-             else
-               return;
-           }
-       }
-      else if (token->type == CPP_CLOSE_PAREN)
-       {
-         /* Close a scope if requested.  */
-         if (active_ifs.length () > active_ifs_len)
-           {
-             eat_token (CPP_CLOSE_PAREN);
-             active_ifs.pop ();
-             token = peek ();
-           }
-         else
-           return;
-       }
-      else
-       {
-         if (matcher)
-           fatal_at (token, "expected match operand expression");
-         push_simplify (simplifiers, match, match_location,
-                        matcher ? result : parse_op (), token->src_loc);
-         /* A "default" result closes the enclosing scope.  */
-         if (active_ifs.length () > active_ifs_len)
-           {
-             eat_token (CPP_CLOSE_PAREN);
-             active_ifs.pop ();
-           }
-         else
-           return;
-       }
-      token = peek ();
+      active_if->trueexpr = tem;
+      result = outermost_if;
     }
+  else
+    result = tem;
+
+  push_simplify (kind, simplifiers, match, match_location,
+                result, token->src_loc);
 }
 
 /* Parsing of the outer control structures.  */
@@ -3740,15 +3815,15 @@ parser::parse_operator_list (source_loca
      if = '(' 'if' '(' <c-expr> ')' <pattern> ')'  */
 
 void
-parser::parse_if (source_location loc)
+parser::parse_if (source_location)
 {
-  operand *ifexpr = parse_c_expr (CPP_OPEN_PAREN);
+  c_expr *ifexpr = parse_c_expr (CPP_OPEN_PAREN);
 
   const cpp_token *token = peek ();
   if (token->type == CPP_CLOSE_PAREN)
     fatal_at (token, "no pattern defined in if");
 
-  active_ifs.safe_push (if_or_with (ifexpr, loc, false));
+  active_ifs.safe_push (ifexpr);
   while (1)
     {
       const cpp_token *token = peek ();
@@ -3789,7 +3864,8 @@ parser::parse_pattern ()
   const char *id = get_ident ();
   if (strcmp (id, "simplify") == 0)
     {
-      parse_simplify (token->src_loc, simplifiers, NULL, NULL);
+      parse_simplify (simplify::SIMPLIFY,
+                     token->src_loc, simplifiers, NULL, NULL);
       capture_ids = NULL;
     }
   else if (strcmp (id, "match") == 0)
@@ -3827,7 +3903,7 @@ parser::parse_pattern ()
              || (!e && p->nargs != 0)))
        fatal_at (token, "non-matching number of match operands");
       p->nargs = e ? e->ops.length () : 0;
-      parse_simplify (token->src_loc, p->matchers, p, e);
+      parse_simplify (simplify::MATCH, token->src_loc, p->matchers, p, e);
       capture_ids = NULL;
     }
   else if (strcmp (id, "for") == 0)
Index: gcc/match.pd
===================================================================
--- gcc/match.pd        (revision 225727)
+++ gcc/match.pd        (working copy)
@@ -153,11 +153,10 @@ (define_operator_list CBRT BUILT_IN_CBRT
     wide_int mul = wi::mul (@1, @2, TYPE_SIGN (type), &overflow_p);
    }
    (if (!overflow_p)
-    (div @0 { wide_int_to_tree (type, mul); }))
-   (if (overflow_p
-        && (TYPE_UNSIGNED (type)
-           || mul != wi::min_value (TYPE_PRECISION (type), SIGNED)))
-    { build_zero_cst (type); }))))
+    (div @0 { wide_int_to_tree (type, mul); })
+    (if (TYPE_UNSIGNED (type)
+        || mul != wi::min_value (TYPE_PRECISION (type), SIGNED))
+     { build_zero_cst (type); })))))
 
 /* Optimize A / A to 1.0 if we don't care about
    NaNs or Infinities.  */
@@ -203,11 +202,11 @@ (define_operator_list CBRT BUILT_IN_CBRT
     (with
      { tree tem = const_binop (RDIV_EXPR, type, build_one_cst (type), @1); }
      (if (tem)
-      (mult @0 { tem; } ))))
-   (if (cst != COMPLEX_CST)
-    (with { tree inverse = exact_inverse (type, @1); }
-     (if (inverse)
-      (mult @0 { inverse; } )))))))
+      (mult @0 { tem; } )))
+    (if (cst != COMPLEX_CST)
+     (with { tree inverse = exact_inverse (type, @1); }
+      (if (inverse)
+       (mult @0 { inverse; } ))))))))
 
 /* Same applies to modulo operations, but fold is inconsistent here
    and simplifies 0 % x to 0, only preserving literal 0 % 0.  */
@@ -908,11 +907,11 @@ (define_operator_list CBRT BUILT_IN_CBRT
         being well defined.  */
      (if (low >= prec)
       (if (op == LROTATE_EXPR || op == RROTATE_EXPR)
-       (op @0 { build_int_cst (TREE_TYPE (@1), low % prec); }))
-      (if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
-       { build_zero_cst (type); })
-      (op @0 { build_int_cst (TREE_TYPE (@1), prec - 1); }))
-     (op @0 { build_int_cst (TREE_TYPE (@1), low); }))))))
+       (op @0 { build_int_cst (TREE_TYPE (@1), low % prec); })
+       (if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
+        { build_zero_cst (type); }
+        (op @0 { build_int_cst (TREE_TYPE (@1), prec - 1); })))
+      (op @0 { build_int_cst (TREE_TYPE (@1), low); })))))))
 
 
 /* ((1 << A) & 1) != 0 -> A == 0
@@ -933,10 +932,10 @@ (define_operator_list CBRT BUILT_IN_CBRT
    (if (cand < 0
        || (!integer_zerop (@2)
            && wi::ne_p (wi::lshift (@0, cand), @2)))
-    { constant_boolean_node (cmp == NE_EXPR, type); })
-   (if (!integer_zerop (@2)
-       && wi::eq_p (wi::lshift (@0, cand), @2))
-    (cmp @1 { build_int_cst (TREE_TYPE (@1), cand); })))))
+    { constant_boolean_node (cmp == NE_EXPR, type); }
+    (if (!integer_zerop (@2)
+        && wi::eq_p (wi::lshift (@0, cand), @2))
+     (cmp @1 { build_int_cst (TREE_TYPE (@1), cand); }))))))
 
 /* Fold (X << C1) & C2 into (X << C1) & (C2 | ((1 << C1) - 1))
         (X >> C1) & C2 into (X >> C1) & (C2 | ~((type) -1 >> C1))
@@ -1007,27 +1006,26 @@ (define_operator_list CBRT BUILT_IN_CBRT
      }
      /* ((X << 16) & 0xff00) is (X, 0).  */
      (if ((mask & zerobits) == mask)
-      { build_int_cst (type, 0); })
-     (with { newmask = mask | zerobits; }
-      (if (newmask != mask && (newmask & (newmask + 1)) == 0)
-       (with
-       {
-         /* Only do the transformation if NEWMASK is some integer
-            mode's mask.  */
-         for (prec = BITS_PER_UNIT;
-              prec < HOST_BITS_PER_WIDE_INT; prec <<= 1)
-           if (newmask == (((unsigned HOST_WIDE_INT) 1) << prec) - 1)
-             break;
-       }
-       (if (prec < HOST_BITS_PER_WIDE_INT
-            || newmask == ~(unsigned HOST_WIDE_INT) 0)
-        (with
-         { tree newmaskt = build_int_cst_type (TREE_TYPE (@2), newmask); }
-         (if (!tree_int_cst_equal (newmaskt, @2))
-          (if (shift_type != TREE_TYPE (@3))
-           (bit_and (convert (shift:shift_type (convert @3) @1)) { newmaskt; 
}))
-          (if (shift_type == TREE_TYPE (@3))
-           (bit_and @4 { newmaskt; }))))))))))))
+      { build_int_cst (type, 0); }
+      (with { newmask = mask | zerobits; }
+       (if (newmask != mask && (newmask & (newmask + 1)) == 0)
+        (with
+        {
+          /* Only do the transformation if NEWMASK is some integer
+             mode's mask.  */
+          for (prec = BITS_PER_UNIT;
+               prec < HOST_BITS_PER_WIDE_INT; prec <<= 1)
+            if (newmask == (((unsigned HOST_WIDE_INT) 1) << prec) - 1)
+              break;
+        }
+        (if (prec < HOST_BITS_PER_WIDE_INT
+             || newmask == ~(unsigned HOST_WIDE_INT) 0)
+         (with
+          { tree newmaskt = build_int_cst_type (TREE_TYPE (@2), newmask); }
+          (if (!tree_int_cst_equal (newmaskt, @2))
+           (if (shift_type != TREE_TYPE (@3))
+            (bit_and (convert (shift:shift_type (convert @3) @1)) { newmaskt; 
})
+            (bit_and @4 { newmaskt; })))))))))))))
 
 /* Fold (X & C2) << C1 into (X << C1) & (C2 << C1)
    (X & C2) >> C1 into (X >> C1) & (C2 >> C1).  */
@@ -1119,7 +1117,7 @@ (define_operator_list CBRT BUILT_IN_CBRT
        && (((inter_int || inter_ptr) && final_int)
            || (inter_float && final_float))
        && inter_prec >= final_prec)
-    (ocvt @0))
+    (ocvt @0)
 
    /* Likewise, if the intermediate and initial types are either both
       float or both integer, we don't need the middle conversion if the
@@ -1133,7 +1131,7 @@ (define_operator_list CBRT BUILT_IN_CBRT
        && (inter_float || inter_unsignedp == inside_unsignedp)
        && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type))
              && TYPE_MODE (type) == TYPE_MODE (inter_type)))
-    (ocvt @0))
+    (ocvt @0)
 
    /* If we have a sign-extension of a zero-extended value, we can
       replace that by a single zero-extension.  Likewise if the
@@ -1143,7 +1141,7 @@ (define_operator_list CBRT BUILT_IN_CBRT
        && ((inside_prec < inter_prec && inter_prec < final_prec
             && inside_unsignedp && !inter_unsignedp)
            || final_prec == inter_prec))
-    (ocvt @0))
+    (ocvt @0)
 
    /* Two conversions in a row are not needed unless:
        - some conversion is floating-point (overstrict for now), or
@@ -1168,7 +1166,7 @@ (define_operator_list CBRT BUILT_IN_CBRT
        && ! (final_ptr && inside_prec != inter_prec)
        && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type))
              && TYPE_MODE (type) == TYPE_MODE (inter_type)))
-    (ocvt @0))
+    (ocvt @0)
 
    /* A truncation to an unsigned type (a zero-extension) should be
       canonicalized as bitwise and of a mask.  */
@@ -1179,7 +1177,7 @@ (define_operator_list CBRT BUILT_IN_CBRT
     (convert (bit_and @0 { wide_int_to_tree
                             (inside_type,
                              wi::mask (inter_prec, false,
-                                       TYPE_PRECISION (inside_type))); })))
+                                       TYPE_PRECISION (inside_type))); }))
 
    /* If we are converting an integer to a floating-point that can
       represent it exactly and back to an integer, we can skip the
@@ -1188,7 +1186,7 @@ (define_operator_list CBRT BUILT_IN_CBRT
        && inside_int && inter_float && final_int &&
        (unsigned) significand_size (TYPE_MODE (inter_type))
        >= inside_prec - !inside_unsignedp)
-    (convert @0))))))
+    (convert @0)))))))))))
 
 /* If we have a narrowing conversion to an integral type that is fed by a
    BIT_AND_EXPR, we might be able to remove the BIT_AND_EXPR if it merely
@@ -1281,20 +1279,17 @@ (define_operator_list CBRT BUILT_IN_CBRT
    genmatch cannot handle.  */
 (simplify
  (cond INTEGER_CST@0 @1 @2)
- (if (integer_zerop (@0)
-      && (!VOID_TYPE_P (TREE_TYPE (@2))
-         || VOID_TYPE_P (type)))
-  @2)
- (if (!integer_zerop (@0)
-      && (!VOID_TYPE_P (TREE_TYPE (@1))
-         || VOID_TYPE_P (type)))
-  @1))
+ (if (integer_zerop (@0))
+  (if (!VOID_TYPE_P (TREE_TYPE (@2)) || VOID_TYPE_P (type))
+   @2)
+  (if (!VOID_TYPE_P (TREE_TYPE (@1)) || VOID_TYPE_P (type))
+   @1)))
 (simplify
  (vec_cond VECTOR_CST@0 @1 @2)
  (if (integer_all_onesp (@0))
-  @1)
- (if (integer_zerop (@0))
-  @2))
+  @1
+  (if (integer_zerop (@0))
+   @2)))
 
 (for cnd (cond vec_cond)
  /* A ? B : (A ? X : C) -> A ? B : C.  */
@@ -1362,17 +1357,17 @@ (define_operator_list CBRT BUILT_IN_CBRT
    (with { enum tree_code ic = invert_tree_comparison
              (cmp, HONOR_NANS (@0)); }
     (if (ic == icmp)
-     (icmp @0 @1))
-    (if (ic == ncmp)
-     (ncmp @0 @1)))))
+     (icmp @0 @1)
+     (if (ic == ncmp)
+      (ncmp @0 @1))))))
  (simplify
   (bit_xor (cmp @0 @1) integer_truep)
   (with { enum tree_code ic = invert_tree_comparison
             (cmp, HONOR_NANS (@0)); }
    (if (ic == icmp)
-    (icmp @0 @1))
-   (if (ic == ncmp)
-    (ncmp @0 @1)))))
+    (icmp @0 @1)
+    (if (ic == ncmp)
+     (ncmp @0 @1))))))
 
 /* Transform comparisons of the form X - Y CMP 0 to X CMP Y.
    ??? The transformation is valid for the other operators if overflow
@@ -1395,13 +1390,13 @@ (define_operator_list CBRT BUILT_IN_CBRT
   (cmp (mult @0 INTEGER_CST@1) integer_zerop@2)
   /* Handle unfolded multiplication by zero.  */
   (if (integer_zerop (@1))
-   (cmp @1 @2))
-  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
-       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
-   /* If @1 is negative we swap the sense of the comparison.  */
-   (if (tree_int_cst_sgn (@1) < 0)
-    (scmp @0 @2))
-   (cmp @0 @2))))
+   (cmp @1 @2)
+   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+    /* If @1 is negative we swap the sense of the comparison.  */
+    (if (tree_int_cst_sgn (@1) < 0)
+     (scmp @0 @2)
+     (cmp @0 @2))))))
  
 /* Simplify comparison of something with itself.  For IEEE
    floating-point, we can only do some of these simplifications.  */
@@ -1470,11 +1465,11 @@ (define_operator_list CBRT BUILT_IN_CBRT
   /* IEEE doesn't distinguish +0 and -0 in comparisons.  */
   /* a CMP (-0) -> a CMP 0  */
   (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@1)))
-   (cmp @0 { build_real (TREE_TYPE (@1), dconst0); }))
+   (cmp @0 { build_real (TREE_TYPE (@1), dconst0); })
   /* x != NaN is always true, other ops are always false.  */
   (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
        && ! HONOR_SNANS (@1))
-   { constant_boolean_node (cmp == NE_EXPR, type); })
+   { constant_boolean_node (cmp == NE_EXPR, type); }
   /* Fold comparisons against infinity.  */
   (if (REAL_VALUE_ISINF (TREE_REAL_CST (@1))
        && MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (@1))))
@@ -1489,37 +1484,37 @@ (define_operator_list CBRT BUILT_IN_CBRT
     /* x > +Inf is always false, if with ignore sNANs.  */
     (if (code == GT_EXPR
         && ! HONOR_SNANS (@0))
-     { constant_boolean_node (false, type); })
+     { constant_boolean_node (false, type); }
     (if (code == LE_EXPR)
      /* x <= +Inf is always true, if we don't case about NaNs.  */
      (if (! HONOR_NANS (@0))
-      { constant_boolean_node (true, type); })
-     /* x <= +Inf is the same as x == x, i.e. isfinite(x).  */
-     (eq @0 @0))
+      { constant_boolean_node (true, type); }
+      /* x <= +Inf is the same as x == x, i.e. isfinite(x).  */
+      (eq @0 @0))
     /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX.  */
     (if (code == EQ_EXPR || code == GE_EXPR)
      (with { real_maxval (&max, neg, TYPE_MODE (TREE_TYPE (@0))); }
       (if (neg)
-       (lt @0 { build_real (TREE_TYPE (@0), max); }))
-      (gt @0 { build_real (TREE_TYPE (@0), max); })))
+       (lt @0 { build_real (TREE_TYPE (@0), max); })
+       (gt @0 { build_real (TREE_TYPE (@0), max); })))
     /* x < +Inf is always equal to x <= DBL_MAX.  */
     (if (code == LT_EXPR)
      (with { real_maxval (&max, neg, TYPE_MODE (TREE_TYPE (@0))); }
       (if (neg)
-       (ge @0 { build_real (TREE_TYPE (@0), max); }))
-      (le @0 { build_real (TREE_TYPE (@0), max); })))
+       (ge @0 { build_real (TREE_TYPE (@0), max); })
+       (le @0 { build_real (TREE_TYPE (@0), max); })))
     /* x != +Inf is always equal to !(x > DBL_MAX).  */
     (if (code == NE_EXPR)
      (with { real_maxval (&max, neg, TYPE_MODE (TREE_TYPE (@0))); }
       (if (! HONOR_NANS (@0))
        (if (neg)
-        (ge @0 { build_real (TREE_TYPE (@0), max); }))
-       (le @0 { build_real (TREE_TYPE (@0), max); }))
-      (if (neg)
-       (bit_xor (lt @0 { build_real (TREE_TYPE (@0), max); })
-               { build_one_cst (type); }))
-      (bit_xor (gt @0 { build_real (TREE_TYPE (@0), max); })
-       { build_one_cst (type); }))))))
+        (ge @0 { build_real (TREE_TYPE (@0), max); })
+       (le @0 { build_real (TREE_TYPE (@0), max); }))
+       (if (neg)
+       (bit_xor (lt @0 { build_real (TREE_TYPE (@0), max); })
+                       { build_one_cst (type); })
+       (bit_xor (gt @0 { build_real (TREE_TYPE (@0), max); })
+                       { build_one_cst (type); }))))))))))))))
 
  /* If this is a comparison of a real constant with a PLUS_EXPR
     or a MINUS_EXPR of a real constant, we can convert it into a
@@ -1557,13 +1552,13 @@ (define_operator_list CBRT BUILT_IN_CBRT
     (if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (@1)))
      /* sqrt(x) < y is always false, if y is negative.  */
      (if (cmp == EQ_EXPR || cmp == LT_EXPR || cmp == LE_EXPR)
-      { constant_boolean_node (false, type); })
+      { constant_boolean_node (false, type); }
      /* sqrt(x) > y is always true, if y is negative and we
        don't care about NaNs, i.e. negative values of x.  */
      (if (cmp == NE_EXPR || !HONOR_NANS (@0))
-      { constant_boolean_node (true, type); })
+      { constant_boolean_node (true, type); }
      /* sqrt(x) > y is the same as x >= 0, if y is negative.  */
-     (ge @0 { build_real (TREE_TYPE (@0), dconst0); }))
+     (ge @0 { build_real (TREE_TYPE (@0), dconst0); })))
     (if (cmp == GT_EXPR || cmp == GE_EXPR)
      (with
       {
@@ -1574,10 +1569,10 @@ (define_operator_list CBRT BUILT_IN_CBRT
       (if (REAL_VALUE_ISINF (c2))
        /* sqrt(x) > y is x == +Inf, when y is very large.  */
        (if (HONOR_INFINITIES (@0))
-        (eq @0 { build_real (TREE_TYPE (@0), c2); }))
-       { constant_boolean_node (false, type); })
-      /* sqrt(x) > c is the same as x > c*c.  */
-      (cmp @0 { build_real (TREE_TYPE (@0), c2); })))
+        (eq @0 { build_real (TREE_TYPE (@0), c2); })
+       { constant_boolean_node (false, type); })
+       /* sqrt(x) > c is the same as x > c*c.  */
+       (cmp @0 { build_real (TREE_TYPE (@0), c2); })))
     (if (cmp == LT_EXPR || cmp == LE_EXPR)
      (with
       {
@@ -1589,30 +1584,30 @@ (define_operator_list CBRT BUILT_IN_CBRT
        /* sqrt(x) < y is always true, when y is a very large
          value and we don't care about NaNs or Infinities.  */
        (if (! HONOR_NANS (@0) && ! HONOR_INFINITIES (@0))
-        { constant_boolean_node (true, type); })
+        { constant_boolean_node (true, type); }
        /* sqrt(x) < y is x != +Inf when y is very large and we
          don't care about NaNs.  */
        (if (! HONOR_NANS (@0))
-        (ne @0 { build_real (TREE_TYPE (@0), c2); }))
+        (ne @0 { build_real (TREE_TYPE (@0), c2); })
        /* sqrt(x) < y is x >= 0 when y is very large and we
          don't care about Infinities.  */
        (if (! HONOR_INFINITIES (@0))
-        (ge @0 { build_real (TREE_TYPE (@0), dconst0); }))
+        (ge @0 { build_real (TREE_TYPE (@0), dconst0); })
        /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large.  */
        (if (GENERIC)
         (truth_andif
         (ge @0 { build_real (TREE_TYPE (@0), dconst0); })
-        (ne @0 { build_real (TREE_TYPE (@0), c2); }))))
+        (ne @0 { build_real (TREE_TYPE (@0), c2); }))))))
       /* sqrt(x) < c is the same as x < c*c, if we ignore NaNs.  */
       (if (! REAL_VALUE_ISINF (c2)
            && ! HONOR_NANS (@0))
-       (cmp @0 { build_real (TREE_TYPE (@0), c2); }))
+       (cmp @0 { build_real (TREE_TYPE (@0), c2); })
       /* sqrt(x) < c is the same as x >= 0 && x < c*c.  */
       (if (! REAL_VALUE_ISINF (c2)
            && GENERIC)
        (truth_andif
         (ge @0 { build_real (TREE_TYPE (@0), dconst0); })
-       (cmp @0 { build_real (TREE_TYPE (@0), c2); })))))))))
+       (cmp @0 { build_real (TREE_TYPE (@0), c2); })))))))))))))
 
 /* Unordered tests if either argument is a NaN.  */
 (simplify
@@ -1782,9 +1777,9 @@ (define_operator_list CBRT BUILT_IN_CBRT
         && types_match (@0, @1)
         && types_match (@0, type))
       (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
-       (convert (op @0 @1)))
-      (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
-       (convert (op (convert:utype @0) (convert:utype @1)))))))
+       (convert (op @0 @1))
+       (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
+        (convert (op (convert:utype @0) (convert:utype @1))))))))
 
 /* This is another case of narrowing, specifically when there's an outer
    BIT_AND_EXPR which masks off bits outside the type of the innermost
@@ -1792,32 +1787,31 @@ (define_operator_list CBRT BUILT_IN_CBRT
    to unsigned types to avoid introducing undefined behaviour for the
    arithmetic operation.  */
 (for op (minus plus)
-  (simplify
-    (bit_and (op:s (convert@2 @0) (convert@3 @1)) INTEGER_CST@4)
-    (if (INTEGRAL_TYPE_P (type)
-        /* We check for type compatibility between @0 and @1 below,
-           so there's no need to check that @1/@3 are integral types.  */
-        && INTEGRAL_TYPE_P (TREE_TYPE (@0))
-        && INTEGRAL_TYPE_P (TREE_TYPE (@2))
-        /* The precision of the type of each operand must match the
-           precision of the mode of each operand, similarly for the
-           result.  */
-        && (TYPE_PRECISION (TREE_TYPE (@0))
-            == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@0))))
-        && (TYPE_PRECISION (TREE_TYPE (@1))
-            == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@1))))
-        && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
-        /* The inner conversion must be a widening conversion.  */
-        && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
-        && types_match (@0, @1)
-        && (tree_int_cst_min_precision (@4, TYPE_SIGN (TREE_TYPE (@0)))
-            <= TYPE_PRECISION (TREE_TYPE (@0)))
-        && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))
-            || tree_int_cst_sgn (@4) >= 0))
-      (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
-       (with { tree ntype = TREE_TYPE (@0); }
-         (convert (bit_and (op @0 @1) (convert:ntype @4)))))
-      (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
-       (convert (bit_and (op (convert:utype @0) (convert:utype @1))
-                         (convert:utype @4)))))))
-
+ (simplify
+  (bit_and (op:s (convert@2 @0) (convert@3 @1)) INTEGER_CST@4)
+  (if (INTEGRAL_TYPE_P (type)
+       /* We check for type compatibility between @0 and @1 below,
+         so there's no need to check that @1/@3 are integral types.  */
+       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && INTEGRAL_TYPE_P (TREE_TYPE (@2))
+       /* The precision of the type of each operand must match the
+         precision of the mode of each operand, similarly for the
+         result.  */
+       && (TYPE_PRECISION (TREE_TYPE (@0))
+          == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@0))))
+       && (TYPE_PRECISION (TREE_TYPE (@1))
+          == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@1))))
+       && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
+       /* The inner conversion must be a widening conversion.  */
+       && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
+       && types_match (@0, @1)
+       && (tree_int_cst_min_precision (@4, TYPE_SIGN (TREE_TYPE (@0)))
+          <= TYPE_PRECISION (TREE_TYPE (@0)))
+       && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))
+          || tree_int_cst_sgn (@4) >= 0))
+   (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+    (with { tree ntype = TREE_TYPE (@0); }
+     (convert (bit_and (op @0 @1) (convert:ntype @4))))
+    (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
+     (convert (bit_and (op (convert:utype @0) (convert:utype @1))
+              (convert:utype @4))))))))

Reply via email to