-/* For an expression that has the form
- (A && B) || ~B
- or
- (A || B) && ~B,
- we can drop one of the inner expressions and simplify to
- A || ~B
- or
- A && ~B
- LOC is the location of the resulting expression. OP is the inner
- logical operation; the left-hand side in the examples above, while CMPOP
- is the right-hand side. RHS_ONLY is used to prevent us from accidentally
- removing a condition that guards another, as in
- (A != NULL && A->...) || A == NULL
- which we must not transform. If RHS_ONLY is true, only eliminate the
- right-most operand of the inner logical operation. */
-
-static tree
-merge_truthop_with_opposite_arm (location_t loc, tree op, tree cmpop,
- bool rhs_only)
-{
- tree type = TREE_TYPE (cmpop);
- enum tree_code code = TREE_CODE (cmpop);
- enum tree_code truthop_code = TREE_CODE (op);
- tree lhs = TREE_OPERAND (op, 0);
- tree rhs = TREE_OPERAND (op, 1);
- tree orig_lhs = lhs, orig_rhs = rhs;
- enum tree_code rhs_code = TREE_CODE (rhs);
- enum tree_code lhs_code = TREE_CODE (lhs);
- enum tree_code inv_code;
-
- if (TREE_SIDE_EFFECTS (op) || TREE_SIDE_EFFECTS (cmpop))
- return NULL_TREE;
-
- if (TREE_CODE_CLASS (code) != tcc_comparison)
- return NULL_TREE;
-
- if (rhs_code == truthop_code)
- {
- tree newrhs = merge_truthop_with_opposite_arm (loc, rhs, cmpop, rhs_only);
- if (newrhs != NULL_TREE)
- {
- rhs = newrhs;
- rhs_code = TREE_CODE (rhs);
- }
- }
- if (lhs_code == truthop_code && !rhs_only)
- {
- tree newlhs = merge_truthop_with_opposite_arm (loc, lhs, cmpop, false);
- if (newlhs != NULL_TREE)
- {
- lhs = newlhs;
- lhs_code = TREE_CODE (lhs);
- }
- }
-
- inv_code = invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (type)));
- if (inv_code == rhs_code
- && operand_equal_p (TREE_OPERAND (rhs, 0), TREE_OPERAND (cmpop, 0), 0)
- && operand_equal_p (TREE_OPERAND (rhs, 1), TREE_OPERAND (cmpop, 1), 0))
- return lhs;
- if (!rhs_only && inv_code == lhs_code
- && operand_equal_p (TREE_OPERAND (lhs, 0), TREE_OPERAND (cmpop, 0), 0)
- && operand_equal_p (TREE_OPERAND (lhs, 1), TREE_OPERAND (cmpop, 1), 0))
- return rhs;
- if (rhs != orig_rhs || lhs != orig_lhs)
- return fold_build2_loc (loc, truthop_code, TREE_TYPE (cmpop),
- lhs, rhs);
- return NULL_TREE;
-}
-