On Wed, May 05, 2021 at 01:39:32PM +0200, Richard Biener wrote: > Can you in the above IL snippets mark COND_BB and MIDDLE_BB? ... Thanks. Here is an updated patch (attached) and interdiff from previous patch. Ok for trunk if it passes bootstrap/regtest? --- gcc/tree-ssa-phiopt.c 2021-05-03 17:49:54.233300624 +0200 +++ gcc/tree-ssa-phiopt.c 2021-05-05 15:06:23.253189139 +0200 @@ -65,7 +65,7 @@ static bool xor_replacement (basic_block, basic_block, edge, edge, gimple *, tree, tree); static bool spaceship_replacement (basic_block, basic_block, - edge, edge, gimple *, tree, tree); + edge, edge, gphi *, tree, tree); static bool cond_removal_in_popcount_clz_ctz_pattern (basic_block, basic_block, edge, edge, gimple *, tree, tree); @@ -1840,53 +1840,53 @@ /* Attempt to optimize (x <=> y) cmp 0 and similar comparisons. For strong ordering <=> try to match something like: - : + : // cond3_bb (== cond2_bb) if (x_4(D) != y_5(D)) goto ; [INV] else goto ; [INV] - : + : // cond_bb if (x_4(D) < y_5(D)) goto ; [INV] else goto ; [INV] - : + : // middle_bb - : + : // phi_bb # iftmp.0_2 = PHI <1(4), 0(2), -1(3)> _1 = iftmp.0_2 == 0; and for partial ordering <=> something like: - : + : // cond3_bb if (a_3(D) == b_5(D)) goto ; [50.00%] else goto ; [50.00%] - [local count: 536870913]: + [local count: 536870913]: // cond2_bb if (a_3(D) < b_5(D)) goto ; [50.00%] else goto ; [50.00%] - [local count: 268435456]: + [local count: 268435456]: // cond_bb if (a_3(D) > b_5(D)) goto ; [50.00%] else goto ; [50.00%] - [local count: 134217728]: + [local count: 134217728]: // middle_bb - [local count: 1073741824]: + [local count: 1073741824]: // phi_bb # SR.27_4 = PHI <0(2), -1(3), 1(4), 2(5)> _2 = SR.27_4 > 0; */ static bool spaceship_replacement (basic_block cond_bb, basic_block middle_bb, - edge e0, edge e1, gimple *phi, + edge e0, edge e1, gphi *phi, tree arg0, tree arg1) { if (!INTEGRAL_TYPE_P (TREE_TYPE (PHI_RESULT (phi))) @@ -1897,6 +1897,11 @@ || !IN_RANGE (tree_to_shwi (arg1), -1, 2)) return false; + basic_block phi_bb = gimple_bb (phi); + gcc_assert (phi_bb == e0->dest && phi_bb == e1->dest); + if (!IN_RANGE (EDGE_COUNT (phi_bb->preds), 3, 4)) + return false; + use_operand_p use_p; gimple *use_stmt; if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi))) @@ -1953,11 +1958,6 @@ if (!empty_block_p (middle_bb)) return false; - basic_block phi_bb = gimple_bb (phi); - gcc_assert (phi_bb == e0->dest && phi_bb == e1->dest); - if (!IN_RANGE (EDGE_COUNT (phi_bb->preds), 3, 4)) - return false; - gcond *cond1 = as_a (last_stmt (cond_bb)); enum tree_code cmp1 = gimple_cond_code (cond1); if (cmp1 != LT_EXPR && cmp1 != GT_EXPR) @@ -1965,7 +1965,7 @@ tree lhs1 = gimple_cond_lhs (cond1); tree rhs1 = gimple_cond_rhs (cond1); /* The optimization may be unsafe due to NaNs. */ - if (HONOR_NANS (TREE_TYPE (lhs1)) || HONOR_SIGNED_ZEROS (TREE_TYPE (lhs1))) + if (HONOR_NANS (TREE_TYPE (lhs1))) return false; if (TREE_CODE (lhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs1)) return false; @@ -2180,11 +2180,6 @@ gimple_assign_set_rhs1 (use_stmt, cond); } update_stmt (use_stmt); - if (cmp3 == EQ_EXPR) - gimple_cond_make_true (as_a (cond3)); - else - gimple_cond_make_false (as_a (cond3)); - update_stmt (cond3); if (MAY_HAVE_DEBUG_BIND_STMTS) { @@ -2201,6 +2196,13 @@ if (has_debug_uses) { + /* If there are debug uses, emit something like: + # DEBUG D#1 => i_2(D) > j_3(D) ? 1 : -1 + # DEBUG D#2 => i_2(D) == j_3(D) ? 0 : D#1 + where > stands for the comparison that yielded 1 + and replace debug uses of phi result with that D#2. + Ignore the value of 2, because if NaNs aren't expected, + all floating point numbers should be comparable. */ gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi)); tree type = TREE_TYPE (PHI_RESULT (phi)); tree temp1 = make_node (DEBUG_EXPR_DECL); @@ -2224,6 +2226,9 @@ } } + gimple_stmt_iterator psi = gsi_for_stmt (phi); + remove_phi_node (&psi, true); + return true; } Jakub