diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
commit | 071b4126c613881f4cb25b4e5c39032964827f88 (patch) | |
tree | 7ed805786566918630d1d617b1ed8f7310f5fd8e /gcc/tree-ssa-math-opts.cc | |
parent | 845d23f3ea08ba873197c275a8857eee7edad996 (diff) | |
parent | caa1c2f42691d68af4d894a5c3e700ecd2dba080 (diff) | |
download | gcc-devel/gfortran-test.zip gcc-devel/gfortran-test.tar.gz gcc-devel/gfortran-test.tar.bz2 |
Merge branch 'master' into gfortran-testdevel/gfortran-test
Diffstat (limited to 'gcc/tree-ssa-math-opts.cc')
-rw-r--r-- | gcc/tree-ssa-math-opts.cc | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index ca98205..bfad4cf 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -4241,6 +4241,39 @@ match_unsigned_saturation_mul (gimple_stmt_iterator *gsi, gassign *stmt) ops[0], ops[1]); } +/* Try to match saturation unsigned mul, aka: + _6 = .MUL_OVERFLOW (a_4(D), b_5(D)); + _2 = IMAGPART_EXPR <_6>; + if (_2 != 0) + goto <bb 4>; [35.00%] + else + goto <bb 3>; [65.00%] + + <bb 3> [local count: 697932184]: + _1 = REALPART_EXPR <_6>; + + <bb 4> [local count: 1073741824]: + # _3 = PHI <18446744073709551615(2), _1(3)> + => + _3 = .SAT_MUL (a_4(D), b_5(D)); */ + +static bool +match_saturation_mul (gimple_stmt_iterator *gsi, gphi *phi) +{ + if (gimple_phi_num_args (phi) != 2) + return false; + + tree ops[2]; + tree phi_result = gimple_phi_result (phi); + + if (!gimple_unsigned_integer_sat_mul (phi_result, ops, NULL)) + return false; + + return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_MUL, + phi_result, ops[0], + ops[1]); +} + /* * Try to match saturation unsigned sub. * <bb 2> [local count: 1073741824]: @@ -6052,9 +6085,9 @@ convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi) conditional jump sequence. If the <bb 6> [local count: 1073741824]: above has a single PHI like: - # _27 = PHI<0(2), -1(3), 2(4), 1(5)> + # _27 = PHI<0(2), -1(3), -128(4), 1(5)> then replace it with effectively - _1 = .SPACESHIP (a_2(D), b_3(D), 1); + _1 = .SPACESHIP (a_2(D), b_3(D), -128); _27 = _1; */ static void @@ -6185,7 +6218,7 @@ optimize_spaceship (gcond *stmt) than 0 as last .SPACESHIP argument to tell backends it might consider different code generation and just cast the result of .SPACESHIP to the PHI result. X above is some value - other than -1, 0, 1, for libstdc++ 2, for libc++ -127. */ + other than -1, 0, 1, for libstdc++ -128, for libc++ -127. */ tree arg3 = integer_zero_node; edge e = EDGE_SUCC (bb0, 0); if (e->dest == bb1) @@ -6212,7 +6245,8 @@ optimize_spaceship (gcond *stmt) && integer_zerop (gimple_phi_arg_def_from_edge (phi, e)) && EDGE_COUNT (bbp->preds) == (HONOR_NANS (TREE_TYPE (arg1)) ? 4 : 3)) { - HOST_WIDE_INT argval = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? 2 : -1; + HOST_WIDE_INT argval + = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? -128 : -1; for (unsigned i = 0; phi && i < EDGE_COUNT (bbp->preds) - 1; ++i) { edge e3 = i == 0 ? e1 : i == 1 ? em1 : e2; @@ -6271,7 +6305,7 @@ optimize_spaceship (gcond *stmt) if (HONOR_NANS (TREE_TYPE (arg1))) { if (arg3 == integer_zero_node) - wmax = wi::two (TYPE_PRECISION (integer_type_node)); + wmin = wi::shwi (-128, TYPE_PRECISION (integer_type_node)); else if (tree_int_cst_sgn (arg3) < 0) wmin = wi::to_wide (arg3); else @@ -6417,7 +6451,8 @@ math_opts_dom_walker::after_dom_children (basic_block bb) if (match_saturation_add (&gsi, phi) || match_saturation_sub (&gsi, phi) - || match_saturation_trunc (&gsi, phi)) + || match_saturation_trunc (&gsi, phi) + || match_saturation_mul (&gsi, phi)) remove_phi_node (&psi, /* release_lhs_p */ false); } |