Hello,I noticed this one with BIT_NOT_EXPR a while ago. C++ testcase because I haven't looked at gimplefe yet...
2019-05-20 Marc Glisse <marc.gli...@inria.fr> gcc/ * match.pd (~(vec?cst1:cst2)); New transformation. gcc/testsuite/ * g++.dg/tree-ssa/cprop-vcond.C -- Marc Glisse
Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 271376) +++ gcc/match.pd (working copy) @@ -2911,20 +2913,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) @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))) +/* Sink unary operations to constant branches. */ +(for op (negate bit_not abs absu) + (simplify + (op (vec_cond @0 VECTOR_CST@1 VECTOR_CST@2)) + (vec_cond @0 (op @1) (op @2)))) + /* Simplification moved from fold_cond_expr_with_comparison. It may also be extended. */ /* This pattern implements two kinds simplification: Case 1) (cond (cmp (convert1? x) c1) (convert2? x) c2) -> (minmax (x c)) if: 1) Conversions are type widening from smaller type. 2) Const c1 equals to c2 after canonicalizing comparison. 3) Comparison has tree code LT, LE, GT or GE. This specific pattern is needed when (cmp (convert x) c) may not Index: gcc/testsuite/g++.dg/tree-ssa/cprop-vcond.C =================================================================== --- gcc/testsuite/g++.dg/tree-ssa/cprop-vcond.C (nonexistent) +++ gcc/testsuite/g++.dg/tree-ssa/cprop-vcond.C (working copy) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop1-raw" } */ + +typedef long vec __attribute__((vector_size(2*sizeof(long)))); +void f(vec*v){ + vec t = { 5, 16 }; + vec f = { 27, -11 }; + vec r = *v ? t : f; + *v = -r; +} + +/* { dg-final { scan-tree-dump-not "negate_expr" "forwprop1" } } */