+/* The function value_replacement does the main work of doing the value
+ replacement. Return true if the replacement is done. Otherwise return
+ false.
+ BB is the basic block where the replacement is going to be done on. ARG0
+ is argument 0 from the PHI. Likewise for ARG1. */
+
+static bool
+value_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
+{
+ tree result;
+ basic_block other_block = NULL;
+ basic_block cond_block = NULL;
+ tree new, cond;
+ edge true_edge, false_edge;
+
+ /* If the type says honor signed zeros we cannot do this
+ optimization. */
+ if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
+ return false;
+
+ if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block))
+ return false;
+
+ cond = COND_EXPR_COND (last_stmt (cond_block));
+ result = PHI_RESULT (phi);
+
+ /* This transformation is only valid for equality comparisons. */
+ if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
+ return false;
+
+ /* We need to know which is the true edge and which is the false
+ edge so that we know if have abs or negative abs. */
+ extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
+
+ /* At this point we know we have a COND_EXPR with two successors.
+ One successor is BB, the other successor is an empty block which
+ falls through into BB.
+
+ The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
+
+ There is a single PHI node at the join point (BB) with two arguments.
+
+ We now need to verify that the two arguments in the PHI node match
+ the two arguments to the equality comparison. */
+
+ if ((operand_equal_p (arg0, TREE_OPERAND (cond, 0), 0)
+ && operand_equal_p (arg1, TREE_OPERAND (cond, 1), 0))
+ || (operand_equal_p (arg1, TREE_OPERAND (cond, 0), 0)
+ && operand_equal_p (arg0, TREE_OPERAND (cond, 1), 0)))
+ {
+ edge e;
+ tree arg;
+
+ e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
+ if (PHI_ARG_EDGE (phi, 0) == e)
+ arg = arg0;
+ else
+ arg = arg1;
+
+ /* Build the new assignment. */
+ new = build (MODIFY_EXPR, TREE_TYPE (result), result, arg);
+
+ replace_phi_with_stmt (bsi_start (bb), bb, cond_block, phi, new);
+
+ /* Note that we optimized this PHI. */
+ return true;
+ }
+ return false;
+}
+