Re: [PATCH, match] Fix pr68714

2016-03-19 Thread Jakub Jelinek
On Tue, Mar 15, 2016 at 08:09:54AM -0700, Richard Henderson wrote:
> Ah, sure.  I should have simply tested the reassoc1 dump file, before
> generic vector lowering.

The testcase fails on i386 (and I assume fails on powerpc too), due to the
psABI warnings/notes.

I've committed this as obvious.

2016-03-16  Jakub Jelinek  

PR tree-optimization/68714
* gcc.dg/tree-ssa/pr68714.c: Add -w -Wno-psabi to dg-options.

--- gcc/testsuite/gcc.dg/tree-ssa/pr68714.c.jj  2016-03-15 17:10:18.627539190 
+0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr68714.c 2016-03-16 14:20:34.160133852 
+0100
@@ -1,5 +1,6 @@
+/* PR tree-optimization/68714 */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-reassoc1" } */
+/* { dg-options "-O2 -fdump-tree-reassoc1 -w -Wno-psabi" } */
 
 typedef int vec __attribute__((vector_size(16)));
 vec f(vec x,vec y){


Jakub


Re: [PATCH, match] Fix pr68714

2016-03-15 Thread Richard Henderson

On 03/15/2016 02:26 AM, Andreas Schwab wrote:

Richard Henderson  writes:


diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c
new file mode 100644
index 000..741d311
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef int vec __attribute__((vector_size(16)));
+vec f(vec x,vec y){
+  return x

That fails on ia64:

$ grep " <= " pr68714.c.211t.optimized
   _10 = _8 <= _9 ? -1 : 0;
   _13 = _11 <= _12 ? -1 : 0;
   _16 = _14 <= _15 ? -1 : 0;


Ah, sure.  I should have simply tested the reassoc1 dump file, before generic 
vector lowering.



r~



Re: [PATCH, match] Fix pr68714

2016-03-15 Thread Richard Biener
On Tue, 15 Mar 2016, Andreas Schwab wrote:

> Richard Henderson  writes:
> 
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c 
> > b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c
> > new file mode 100644
> > index 000..741d311
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c
> > @@ -0,0 +1,9 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > +
> > +typedef int vec __attribute__((vector_size(16)));
> > +vec f(vec x,vec y){
> > +  return x > +}
> > +
> > +/* { dg-final { scan-tree-dump-times " <= " 1 "optimized" } } */
> 
> That fails on ia64:
> 
> $ grep " <= " pr68714.c.211t.optimized 
>   _10 = _8 <= _9 ? -1 : 0;
>   _13 = _11 <= _12 ? -1 : 0;
>   _16 = _14 <= _15 ? -1 : 0;

Probably on all targets that don't support V4SImode vectors.  Though
three cond_exprs is odd ;)  I suppose we got one DImode and two SImode
but that would be odd behavior from veclower...

Richard.


Re: [PATCH, match] Fix pr68714

2016-03-15 Thread Andreas Schwab
Richard Henderson  writes:

> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c
> new file mode 100644
> index 000..741d311
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +typedef int vec __attribute__((vector_size(16)));
> +vec f(vec x,vec y){
> +  return x +}
> +
> +/* { dg-final { scan-tree-dump-times " <= " 1 "optimized" } } */

That fails on ia64:

$ grep " <= " pr68714.c.211t.optimized 
  _10 = _8 <= _9 ? -1 : 0;
  _13 = _11 <= _12 ? -1 : 0;
  _16 = _14 <= _15 ? -1 : 0;

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


Re: [PATCH, match] Fix pr68714

2016-03-14 Thread Richard Biener
On Fri, 11 Mar 2016, Richard Henderson wrote:

> On 03/02/2016 01:31 AM, Richard Biener wrote:
> > As a general remark I think handling of this simplification is
> > better done in the reassoc pass (see Jakubs comment #4) given
> > || and && associate.  So I'd rather go down that route if possible.
> 
> This seems to do the trick.

There are a lot of tabs vs. white-space issues in the patch.  Otherwise
looks ok to me.

Thanks,
Richard.


Re: [PATCH, match] Fix pr68714

2016-03-11 Thread Richard Henderson

On 03/02/2016 01:31 AM, Richard Biener wrote:

As a general remark I think handling of this simplification is
better done in the reassoc pass (see Jakubs comment #4) given
|| and && associate.  So I'd rather go down that route if possible.


This seems to do the trick.


r~

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c
new file mode 100644
index 000..741d311
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef int vec __attribute__((vector_size(16)));
+vec f(vec x,vec y){
+  return x (SSA_NAME_DEF_STMT (var));
+  if (stmt == NULL)
+return ERROR_MARK;
+
+  /* ??? If we start creating more COND_EXPR, we could perform
+ this same optimization with them.  For now, simplify.  */
+  if (gimple_assign_rhs_code (stmt) != VEC_COND_EXPR)
+return ERROR_MARK;
+
+  tree cond = gimple_assign_rhs1 (stmt);
+  tree_code cmp = TREE_CODE (cond);
+  if (TREE_CODE_CLASS (cmp) != tcc_comparison)
+return ERROR_MARK;
+
+  /* ??? For now, allow only canonical true and false result vectors.
+ We could expand this to other constants should the need arise,
+ but at the moment we don't create them.  */
+  tree t = gimple_assign_rhs2 (stmt);
+  tree f = gimple_assign_rhs3 (stmt);
+  bool inv;
+  if (integer_all_onesp (t))
+inv = false;
+  else if (integer_all_onesp (f))
+{
+  cmp = invert_tree_comparison (cmp, false);
+  inv = true;
+}
+  else
+return ERROR_MARK;
+  if (!integer_zerop (f))
+return ERROR_MARK;
+
+  /* Success!  */
+  if (rets)
+*rets = stmt;
+  if (reti)
+*reti = inv;
+  return cmp;
+}
+
+/* Optimize the condition of VEC_COND_EXPRs which have been combined
+   with OPCODE (either BIT_AND_EXPR or BIT_IOR_EXPR).  */
+
+static bool
+optimize_vec_cond_expr (tree_code opcode, vec *ops)
+{
+  unsigned int length = ops->length (), i, j;
+  bool any_changes = false;
+
+  if (length == 1)
+return false;
+
+  for (i = 0; i < length; ++i)
+{
+  tree elt0 = (*ops)[i]->op;
+
+  gassign *stmt0;
+  bool invert;
+  tree_code cmp0 = ovce_extract_ops (elt0, &stmt0, &invert);
+  if (cmp0 == ERROR_MARK)
+   continue;
+
+  for (j = i + 1; j < length; ++j)
+   {
+ tree &elt1 = (*ops)[j]->op;
+
+ gassign *stmt1;
+  tree_code cmp1 = ovce_extract_ops (elt1, &stmt1, NULL);
+  if (cmp1 == ERROR_MARK)
+   continue;
+
+  tree cond0 = gimple_assign_rhs1 (stmt0);
+ tree x0 = TREE_OPERAND (cond0, 0);
+ tree y0 = TREE_OPERAND (cond0, 1);
+
+  tree cond1 = gimple_assign_rhs1 (stmt1);
+ tree x1 = TREE_OPERAND (cond1, 0);
+ tree y1 = TREE_OPERAND (cond1, 1);
+
+ tree comb;
+ if (opcode == BIT_AND_EXPR)
+   comb = maybe_fold_and_comparisons (cmp0, x0, y0, cmp1, x1, y1);
+ else if (opcode == BIT_IOR_EXPR)
+   comb = maybe_fold_or_comparisons (cmp0, x0, y0, cmp1, x1, y1);
+ else
+   gcc_unreachable ();
+ if (comb == NULL)
+   continue;
+
+ /* Success! */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+   {
+ fprintf (dump_file, "Transforming ");
+ print_generic_expr (dump_file, cond0, 0);
+  fprintf (dump_file, " %c ", opcode == BIT_AND_EXPR ? '&' : '|');
+ print_generic_expr (dump_file, cond1, 0);
+  fprintf (dump_file, " into ");
+ print_generic_expr (dump_file, comb, 0);
+  fputc ('\n', dump_file);
+   }
+
+ gimple_assign_set_rhs1 (stmt0, comb);
+ if (invert)
+   std::swap (*gimple_assign_rhs2_ptr (stmt0),
+  *gimple_assign_rhs3_ptr (stmt0));
+ update_stmt (stmt0);
+
+ elt1 = error_mark_node;
+ any_changes = true;
+   }
+}
+
+  if (any_changes)
+{
+  operand_entry *oe;
+  j = 0;
+  FOR_EACH_VEC_ELT (*ops, i, oe)
+   {
+ if (oe->op == error_mark_node)
+   continue;
+ else if (i != j)
+   (*ops)[j] = oe;
+ j++;
+   }
+  ops->truncate (j);
+}
+
+  return any_changes;
+}
+
 /* Return true if STMT is a cast like:
:
...
@@ -4326,7 +4466,7 @@ static bool
 can_reassociate_p (tree op)
 {
   tree type = TREE_TYPE (op);
-  if ((INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
+  if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
   || NON_SAT_FIXED_POINT_TYPE_P (type)
   || (flag_associative_math && FLOAT_TYPE_P (type)))
 return true;
@@ -4952,6 +5092,7 @@ reassociate_bb (basic_block bb)
{
  auto_vec ops;
  tree powi_result = NULL_TREE;
+ bool is_vector = VECTOR_TYPE_P (TREE_TYPE (lhs));
 
  /* There may be no immediate uses left by the time we
 get here because we may have elimi

Re: [PATCH, match] Fix pr68714

2016-03-02 Thread Richard Biener
On Wed, 2 Mar 2016, Marc Glisse wrote:

> On Wed, 2 Mar 2016, Richard Biener wrote:
> 
> > On Tue, 1 Mar 2016, Richard Henderson wrote:
> > 
> > > This is similar to Mark Gilsse's patch in the OP, except that it ensures
> > > that
> > > the expression will fold back to a single condition.  I did include
> > > Richi's
> > > patch from #c6 to make it more likely to trigger asap.
> > > 
> > > I'd appreciate feedback on the match.pd changes; it's my first time
> > > looking
> > > into this new(ish) mini-language.
> > 
> > The recalculate_side_effects call in the gimplify.c hunk is indented
> > oddly (spaces, no tabs).
> > 
> > Note that nothing guarantees we've canoncalized the cond-exprs
> > to have all-ones in the true path and zero in the false path
> > the pattern will miss three of four cases ... also I don't see
> > why the pattern would need to be restricted to those - shouldn't it
> > simply work for
> > 
> > +  (bcode (vec_cond COMPARISON_CLASS_P@0 @2 @3)
> > +(vec_cond COMPARISON_CLASS_P@1 @2 @3))
> > 
> > ?  That would catch two of four cases ;)
> 
> 
> I don't think that's always valid, you would need that @2 | @3 is the same as
> @2 for the simplification to work for bit_ior (we could use operand_equal_p
> and fold_binary to ask for that, not sure if there is a cleaner way).

Ah, indeed ... :/

> 
> > +   (if (COMPARISON_CLASS_P (folded))
> > + { build3 (VEC_COND_EXPR, TREE_TYPE (@2), folded, @2, @3);
> > })))
> > 
> > this is wrong - you may not build GENERIC trees here.  Instead you
> > want
> > 
> >  (if (COMPARISON_CLASS_P (folded))
> >   (vec_cond { folded; } @2 @3
> > 
> > though even that might be bogus if the operands of the comparison
> > in 'folded' are not is_gimple_val.
> > 
> > Now, building GENERIC via combine_comparisons is somewhat gross
> > in match.pd, simple helpers that can combine two comparison
> > codes would be nicer though the match.pd language doesn't allow
> > easy use of that.  For example handling lt/eq and lt/le combinations
> > requires sth like
> > 
> > (for cnd (cond vec_cond)
> > (for cmp1 (lt eq)
> >  cmp2 (lt lt eq eq)
> >  cmp  (lt le le eq)
> >   (simplify
> >(bit_ior (cnd (cmp1 @0 @1) @2 @3)
> > (cnd (cmp2 @0 @1) @2 @3))
> >(cnd (cmp @0 @1) @2 @3)))
> > (for cmp1 (lt le)
> >  cmp2 (lt lt le le)
> >  cmp  (lt lt lt le)
> >   (simplify
> >(bit_and (cnd (cmp1 @0 @1) @2 @3)
> > (cnd (cmp2 @0 @1) @2 @3))
> >(cnd (cmp @0 @1) @2 @3
> > 
> > and it will also code-generate the comparison outside of the
> > [VEC_]COND_EXPR stmt, thus
> > 
> > _1 = @0 cmp @1;
> > _2 = _1 ? @2 : @3;
> > 
> > that's something we can eventually fix though.  At least it handles
> > both cases in pattern recognition (embedded GENERIC or SSA name).
> > 
> > Note the above still misses the case where @2 and @3 are swapped
> > so you'd have to duplicate things once more.  You also have to
> > be careful to omit comparison codes that will not yield in a
> > combination that can be expressed in a single comparison.
> > 
> > I also noticed the comment I added:
> > 
> > /* ???  This matches embedded conditions open-coded because genmatch
> >would generate matching code for conditions in separate stmts only.
> >The following is still important to merge then and else arm cases
> >from if-conversion.  */
> > 
> > which is techincally wrong - the matching code is just unfortunate
> > (eh...  I'll see to fix that):
> > 
> >switch (gimple_assign_rhs_code (def))
> >  {
> >  case LT_EXPR:
> >{
> > ... SSA name condition handling ...
> >  break;
> >}
> >  case LT_EXPR:<--- oops ;)
> >{
> > ... GENERIC conditon handling ...
> >}
> >  break;
> > 
> > Stupid GIMPLE IL ...
> > 
> > As a general remark I think handling of this simplification is
> > better done in the reassoc pass (see Jakubs comment #4) given
> > || and && associate.  So I'd rather go down that route if possible.
> 
> Still, if there are some easy cases that can be handled early in match.pd,
> that can't hurt... (if there aren't, that's fine)
> Just like x+y+x -> 2*x+y is for reassoc, but x+x -> 2*x can be done in
> match.pd.

True, I was merely looking at the ugliness and incompleteness of the
pattern and wondered if it's really worth doing here as I belive
we need the reassoc code anyway to fix the regression fully.

Richard.


Re: [PATCH, match] Fix pr68714

2016-03-02 Thread Marc Glisse

On Wed, 2 Mar 2016, Richard Biener wrote:


On Tue, 1 Mar 2016, Richard Henderson wrote:


This is similar to Mark Gilsse's patch in the OP, except that it ensures that
the expression will fold back to a single condition.  I did include Richi's
patch from #c6 to make it more likely to trigger asap.

I'd appreciate feedback on the match.pd changes; it's my first time looking
into this new(ish) mini-language.


The recalculate_side_effects call in the gimplify.c hunk is indented
oddly (spaces, no tabs).

Note that nothing guarantees we've canoncalized the cond-exprs
to have all-ones in the true path and zero in the false path
the pattern will miss three of four cases ... also I don't see
why the pattern would need to be restricted to those - shouldn't it
simply work for

+  (bcode (vec_cond COMPARISON_CLASS_P@0 @2 @3)
+(vec_cond COMPARISON_CLASS_P@1 @2 @3))

?  That would catch two of four cases ;)



I don't think that's always valid, you would need that @2 | @3 is the same 
as @2 for the simplification to work for bit_ior (we could use 
operand_equal_p and fold_binary to ask for that, not sure if there is a 
cleaner way).




+   (if (COMPARISON_CLASS_P (folded))
+ { build3 (VEC_COND_EXPR, TREE_TYPE (@2), folded, @2, @3);
})))

this is wrong - you may not build GENERIC trees here.  Instead you
want

 (if (COMPARISON_CLASS_P (folded))
  (vec_cond { folded; } @2 @3

though even that might be bogus if the operands of the comparison
in 'folded' are not is_gimple_val.

Now, building GENERIC via combine_comparisons is somewhat gross
in match.pd, simple helpers that can combine two comparison
codes would be nicer though the match.pd language doesn't allow
easy use of that.  For example handling lt/eq and lt/le combinations
requires sth like

(for cnd (cond vec_cond)
(for cmp1 (lt eq)
 cmp2 (lt lt eq eq)
 cmp  (lt le le eq)
  (simplify
   (bit_ior (cnd (cmp1 @0 @1) @2 @3)
(cnd (cmp2 @0 @1) @2 @3))
   (cnd (cmp @0 @1) @2 @3)))
(for cmp1 (lt le)
 cmp2 (lt lt le le)
 cmp  (lt lt lt le)
  (simplify
   (bit_and (cnd (cmp1 @0 @1) @2 @3)
(cnd (cmp2 @0 @1) @2 @3))
   (cnd (cmp @0 @1) @2 @3

and it will also code-generate the comparison outside of the
[VEC_]COND_EXPR stmt, thus

_1 = @0 cmp @1;
_2 = _1 ? @2 : @3;

that's something we can eventually fix though.  At least it handles
both cases in pattern recognition (embedded GENERIC or SSA name).

Note the above still misses the case where @2 and @3 are swapped
so you'd have to duplicate things once more.  You also have to
be careful to omit comparison codes that will not yield in a
combination that can be expressed in a single comparison.

I also noticed the comment I added:

/* ???  This matches embedded conditions open-coded because genmatch
   would generate matching code for conditions in separate stmts only.
   The following is still important to merge then and else arm cases
   from if-conversion.  */

which is techincally wrong - the matching code is just unfortunate
(eh...  I'll see to fix that):

   switch (gimple_assign_rhs_code (def))
 {
 case LT_EXPR:
   {
... SSA name condition handling ...
 break;
   }
 case LT_EXPR:<--- oops ;)
   {
... GENERIC conditon handling ...
   }
 break;

Stupid GIMPLE IL ...

As a general remark I think handling of this simplification is
better done in the reassoc pass (see Jakubs comment #4) given
|| and && associate.  So I'd rather go down that route if possible.


Still, if there are some easy cases that can be handled early in match.pd, 
that can't hurt... (if there aren't, that's fine)
Just like x+y+x -> 2*x+y is for reassoc, but x+x -> 2*x can be done in 
match.pd.


--
Marc Glisse


Re: [PATCH, match] Fix pr68714

2016-03-02 Thread Richard Biener
On Tue, 1 Mar 2016, Richard Henderson wrote:

> This is similar to Mark Gilsse's patch in the OP, except that it ensures that
> the expression will fold back to a single condition.  I did include Richi's
> patch from #c6 to make it more likely to trigger asap.
> 
> I'd appreciate feedback on the match.pd changes; it's my first time looking
> into this new(ish) mini-language.

The recalculate_side_effects call in the gimplify.c hunk is indented 
oddly (spaces, no tabs).

Note that nothing guarantees we've canoncalized the cond-exprs
to have all-ones in the true path and zero in the false path
the pattern will miss three of four cases ... also I don't see
why the pattern would need to be restricted to those - shouldn't it
simply work for

+  (bcode (vec_cond COMPARISON_CLASS_P@0 @2 @3)
+(vec_cond COMPARISON_CLASS_P@1 @2 @3))

?  That would catch two of four cases ;)

+   (if (COMPARISON_CLASS_P (folded))
+ { build3 (VEC_COND_EXPR, TREE_TYPE (@2), folded, @2, @3); 
})))

this is wrong - you may not build GENERIC trees here.  Instead you
want

  (if (COMPARISON_CLASS_P (folded))
   (vec_cond { folded; } @2 @3

though even that might be bogus if the operands of the comparison
in 'folded' are not is_gimple_val.

Now, building GENERIC via combine_comparisons is somewhat gross
in match.pd, simple helpers that can combine two comparison
codes would be nicer though the match.pd language doesn't allow
easy use of that.  For example handling lt/eq and lt/le combinations
requires sth like

(for cnd (cond vec_cond)
 (for cmp1 (lt eq)
  cmp2 (lt lt eq eq)
  cmp  (lt le le eq)
   (simplify
(bit_ior (cnd (cmp1 @0 @1) @2 @3)
 (cnd (cmp2 @0 @1) @2 @3))
(cnd (cmp @0 @1) @2 @3)))
 (for cmp1 (lt le)
  cmp2 (lt lt le le)
  cmp  (lt lt lt le)
   (simplify
(bit_and (cnd (cmp1 @0 @1) @2 @3)
 (cnd (cmp2 @0 @1) @2 @3))
(cnd (cmp @0 @1) @2 @3

and it will also code-generate the comparison outside of the
[VEC_]COND_EXPR stmt, thus

_1 = @0 cmp @1;
_2 = _1 ? @2 : @3;

that's something we can eventually fix though.  At least it handles
both cases in pattern recognition (embedded GENERIC or SSA name).

Note the above still misses the case where @2 and @3 are swapped
so you'd have to duplicate things once more.  You also have to
be careful to omit comparison codes that will not yield in a
combination that can be expressed in a single comparison.

I also noticed the comment I added:

 /* ???  This matches embedded conditions open-coded because genmatch
would generate matching code for conditions in separate stmts only.
The following is still important to merge then and else arm cases
from if-conversion.  */

which is techincally wrong - the matching code is just unfortunate
(eh...  I'll see to fix that):

switch (gimple_assign_rhs_code (def))
  {
  case LT_EXPR:
{
 ... SSA name condition handling ...
  break;
}
  case LT_EXPR:<--- oops ;)
{
 ... GENERIC conditon handling ...
}
  break;

Stupid GIMPLE IL ...

As a general remark I think handling of this simplification is
better done in the reassoc pass (see Jakubs comment #4) given
|| and && associate.  So I'd rather go down that route if possible.

Thanks,
Richard.


[PATCH, match] Fix pr68714

2016-03-01 Thread Richard Henderson
This is similar to Mark Gilsse's patch in the OP, except that it ensures that
the expression will fold back to a single condition.  I did include Richi's
patch from #c6 to make it more likely to trigger asap.

I'd appreciate feedback on the match.pd changes; it's my first time looking
into this new(ish) mini-language.


r~
* gimplify.c (gimplify_expr) [VEC_COND_EXPR]: Allow the first
argument to be is_gimple_condexpr.
* match.pd: Simplify and + ior of vec_cond.

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 7be6bd7..c434e55 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -10773,8 +10773,21 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
goto expr_2;
  }
 
-   case FMA_EXPR:
case VEC_COND_EXPR:
+ {
+   gimplify_status r0, r1, r2;
+   r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+   post_p, is_gimple_condexpr, fb_rvalue);
+   r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
+   post_p, is_gimple_val, fb_rvalue);
+   r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
+   post_p, is_gimple_val, fb_rvalue);
+   ret = MIN (MIN (r0, r1), r2);
+recalculate_side_effects (*expr_p);
+   break;
+ }
+
+   case FMA_EXPR:
case VEC_PERM_EXPR:
  /* Classified as tcc_expression.  */
  goto expr_3;
diff --git a/gcc/match.pd b/gcc/match.pd
index 5903782..4192d29 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
real_zerop real_onep real_minus_onep
zerop
CONSTANT_CLASS_P
+   COMPARISON_CLASS_P
tree_expr_nonnegative_p
integer_valued_real_p
integer_pow2p
@@ -2452,6 +2453,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
replace if (x == 0) with tem = ~x; if (tem != 0) which is
clearly less optimal and which we'll transform again in forwprop.  */
 
+/* Simplification of vec_cond.  */
+
+(for bcode (bit_and bit_ior)
+ (simplify
+  (bcode (vec_cond COMPARISON_CLASS_P@0 integer_all_onesp@2 integer_zerop@3)
+(vec_cond COMPARISON_CLASS_P@1 @2 @3))
+  (with
+{
+  tree al = TREE_OPERAND (@0, 0);
+  tree ar = TREE_OPERAND (@0, 1);
+  tree bl = TREE_OPERAND (@1, 0);
+  tree br = TREE_OPERAND (@1, 1);
+}
+(if (operand_equal_p (al, bl, 0) && operand_equal_p (ar, br, 0))
+  (with
+   {
+ tree_code tcode
+   = bcode == BIT_AND_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR;
+ tree folded
+   = combine_comparisons (UNKNOWN_LOCATION, tcode, TREE_CODE (@0),
+  TREE_CODE (@1), TREE_TYPE (@0), al, ar);
+   }
+   (if (folded)
+ (switch
+   (if (integer_truep (folded)) @2)
+   (if (integer_zerop (folded)) @3)
+   (if (COMPARISON_CLASS_P (folded))
+ { build3 (VEC_COND_EXPR, TREE_TYPE (@2), folded, @2, @3); })))
+   )
 
 /* Simplification of math builtins.  These rules must all be optimizations
as well as IL simplifications.  If there is a possibility that the new