diff --git a/gcc/match.pd b/gcc/match.pd index 2d3ffc4..d705947 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1800,6 +1800,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && !TYPE_UNSIGNED (TREE_TYPE (@0))) (mult (convert @0) @1))) +/* Narrow integer multiplication by a zero_one_valued_p operand. + Multiplication by [0,1] is guaranteed not to overflow. */ +(simplify + (convert (mult@0 zero_one_valued_p@1 INTEGER_CST@2)) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@0))) + (mult (convert @1) (convert @2)))) + /* Convert ~ (-A) to A - 1. */ (simplify (bit_not (convert? (negate @0))) @@ -4265,6 +4274,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ) #endif +(simplify + (convert (cond@0 @1 INTEGER_CST@2 INTEGER_CST@3)) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@0))) + (cond @1 (convert @2) (convert @3)))) + /* Simplification moved from fold_cond_expr_with_comparison. It may also be extended. */ /* This pattern implements two kinds simplification: diff --git a/gcc/testsuite/gcc.dg/pr105835.c b/gcc/testsuite/gcc.dg/pr105835.c new file mode 100644 index 0000000..354c81c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105835.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +void foo(); + +static int b; + +static short a(short c, unsigned short d) { return c - d; } + +int main() { + int e = -(0 < b); + if (a(1, e)) + b = 0; + else + foo(); +} + +/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */