diff options
Diffstat (limited to 'gcc/tree-ssa-math-opts.cc')
-rw-r--r-- | gcc/tree-ssa-math-opts.cc | 105 |
1 files changed, 96 insertions, 9 deletions
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index 486bdbf..ca98205 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -1053,6 +1053,7 @@ pass_cse_reciprocals::execute (function *fun) continue; gimple_replace_ssa_lhs (call, arg1); + reset_flow_sensitive_info (arg1); if (gimple_call_internal_p (call) != (ifn != IFN_LAST)) { auto_vec<tree, 4> args; @@ -2800,7 +2801,17 @@ convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi) return false; if (actual_precision != TYPE_PRECISION (type1) || from_unsigned1 != TYPE_UNSIGNED (type1)) - type1 = build_nonstandard_integer_type (actual_precision, from_unsigned1); + { + if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1))) + { + if (TREE_CODE (rhs1) == INTEGER_CST) + rhs1 = fold_convert (type1, rhs1); + else + rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1); + } + type1 = build_nonstandard_integer_type (actual_precision, + from_unsigned1); + } if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1))) { if (TREE_CODE (rhs1) == INTEGER_CST) @@ -2810,7 +2821,17 @@ convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi) } if (actual_precision != TYPE_PRECISION (type2) || from_unsigned2 != TYPE_UNSIGNED (type2)) - type2 = build_nonstandard_integer_type (actual_precision, from_unsigned2); + { + if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2))) + { + if (TREE_CODE (rhs2) == INTEGER_CST) + rhs2 = fold_convert (type2, rhs2); + else + rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2); + } + type2 = build_nonstandard_integer_type (actual_precision, + from_unsigned2); + } if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2))) { if (TREE_CODE (rhs2) == INTEGER_CST) @@ -3021,7 +3042,17 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt, actual_precision = GET_MODE_PRECISION (actual_mode); if (actual_precision != TYPE_PRECISION (type1) || from_unsigned1 != TYPE_UNSIGNED (type1)) - type1 = build_nonstandard_integer_type (actual_precision, from_unsigned1); + { + if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1))) + { + if (TREE_CODE (mult_rhs1) == INTEGER_CST) + mult_rhs1 = fold_convert (type1, mult_rhs1); + else + mult_rhs1 = build_and_insert_cast (gsi, loc, type1, mult_rhs1); + } + type1 = build_nonstandard_integer_type (actual_precision, + from_unsigned1); + } if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1))) { if (TREE_CODE (mult_rhs1) == INTEGER_CST) @@ -3031,7 +3062,17 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt, } if (actual_precision != TYPE_PRECISION (type2) || from_unsigned2 != TYPE_UNSIGNED (type2)) - type2 = build_nonstandard_integer_type (actual_precision, from_unsigned2); + { + if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2))) + { + if (TREE_CODE (mult_rhs2) == INTEGER_CST) + mult_rhs2 = fold_convert (type2, mult_rhs2); + else + mult_rhs2 = build_and_insert_cast (gsi, loc, type2, mult_rhs2); + } + type2 = build_nonstandard_integer_type (actual_precision, + from_unsigned2); + } if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2))) { if (TREE_CODE (mult_rhs2) == INTEGER_CST) @@ -4023,6 +4064,7 @@ arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt, extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree)); extern bool gimple_unsigned_integer_sat_sub (tree, tree*, tree (*)(tree)); extern bool gimple_unsigned_integer_sat_trunc (tree, tree*, tree (*)(tree)); +extern bool gimple_unsigned_integer_sat_mul (tree, tree*, tree (*)(tree)); extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree)); extern bool gimple_signed_integer_sat_sub (tree, tree*, tree (*)(tree)); @@ -4064,15 +4106,34 @@ build_saturation_binary_arith_call_and_insert (gimple_stmt_iterator *gsi, * _10 = -_9; * _12 = _7 | _10; * => - * _12 = .SAT_ADD (_4, _6); */ + * _12 = .SAT_ADD (_4, _6); + * + * Try to match IMM=-1 saturation signed add with assign. + * <bb 2> [local count: 1073741824]: + * x.0_1 = (unsigned char) x_5(D); + * _3 = -x.0_1; + * _10 = (signed char) _3; + * _8 = x_5(D) & _10; + * if (_8 < 0) + * goto <bb 4>; [1.40%] + * else + * goto <bb 3>; [98.60%] + * <bb 3> [local count: 434070867]: + * _2 = x.0_1 + 255; + * <bb 4> [local count: 1073741824]: + * # _9 = PHI <_2(3), 128(2)> + * _4 = (int8_t) _9; + * => + * _4 = .SAT_ADD (x_5, -1); */ static void -match_unsigned_saturation_add (gimple_stmt_iterator *gsi, gassign *stmt) +match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt) { tree ops[2]; tree lhs = gimple_assign_lhs (stmt); - if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)) + if (gimple_unsigned_integer_sat_add (lhs, ops, NULL) + || gimple_signed_integer_sat_add (lhs, ops, NULL)) build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD, lhs, ops[0], ops[1]); } @@ -4157,6 +4218,30 @@ match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gassign *stmt) } /* + * Try to match saturation unsigned mul. + * _1 = (unsigned int) a_6(D); + * _2 = (unsigned int) b_7(D); + * x_8 = _1 * _2; + * overflow_9 = x_8 > 255; + * _3 = (unsigned char) overflow_9; + * _4 = -_3; + * _5 = (unsigned char) x_8; + * _10 = _4 | _5; + * => + * _10 = .SAT_SUB (a_6, b_7); */ + +static void +match_unsigned_saturation_mul (gimple_stmt_iterator *gsi, gassign *stmt) +{ + tree ops[2]; + tree lhs = gimple_assign_lhs (stmt); + + if (gimple_unsigned_integer_sat_mul (lhs, ops, NULL)) + build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_MUL, lhs, + ops[0], ops[1]); +} + +/* * Try to match saturation unsigned sub. * <bb 2> [local count: 1073741824]: * if (x_2(D) > y_3(D)) @@ -6363,7 +6448,7 @@ math_opts_dom_walker::after_dom_children (basic_block bb) break; case PLUS_EXPR: - match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt)); + match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt)); match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt)); /* fall-through */ case MINUS_EXPR: @@ -6389,7 +6474,7 @@ math_opts_dom_walker::after_dom_children (basic_block bb) break; case BIT_IOR_EXPR: - match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt)); + match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt)); match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt)); /* fall-through */ case BIT_XOR_EXPR: @@ -6409,7 +6494,9 @@ math_opts_dom_walker::after_dom_children (basic_block bb) break; case NOP_EXPR: + match_unsigned_saturation_mul (&gsi, as_a<gassign *> (stmt)); match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt)); + match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt)); break; default:; |