&& code == NE_EXPR)
return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
- /* Similarly for a BIT_XOR_EXPR; X ^ C1 == C2 is X == (C1 ^ C2). */
- if (TREE_CODE (arg0) == BIT_XOR_EXPR
- && TREE_CODE (arg1) == INTEGER_CST
- && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
- return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0),
- fold_build2_loc (loc, BIT_XOR_EXPR, TREE_TYPE (arg0),
- fold_convert_loc (loc,
- TREE_TYPE (arg0),
- arg1),
- TREE_OPERAND (arg0, 1)));
-
/* Transform comparisons of the form X +- Y CMP X to Y CMP 0. */
if ((TREE_CODE (arg0) == PLUS_EXPR
|| TREE_CODE (arg0) == POINTER_PLUS_EXPR
case UNGE_EXPR:
case UNEQ_EXPR:
case LTGT_EXPR:
- if (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
- {
- t1 = fold_relational_const (code, type, arg0, arg1);
- if (t1 != NULL_TREE)
- return t1;
- }
-
- /* If the first operand is NaN, the result is constant. */
- if (TREE_CODE (arg0) == REAL_CST
- && REAL_VALUE_ISNAN (TREE_REAL_CST (arg0))
- && (code != LTGT_EXPR || ! flag_trapping_math))
- {
- t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
- ? integer_zero_node
- : integer_one_node;
- return omit_one_operand_loc (loc, type, t1, arg1);
- }
-
- /* If the second operand is NaN, the result is constant. */
- if (TREE_CODE (arg1) == REAL_CST
- && REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
- && (code != LTGT_EXPR || ! flag_trapping_math))
- {
- t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
- ? integer_zero_node
- : integer_one_node;
- return omit_one_operand_loc (loc, type, t1, arg0);
- }
-
- /* Simplify unordered comparison of something with itself. */
- if ((code == UNLE_EXPR || code == UNGE_EXPR || code == UNEQ_EXPR)
- && operand_equal_p (arg0, arg1, 0))
- return constant_boolean_node (1, type);
-
- if (code == LTGT_EXPR
- && !flag_trapping_math
- && operand_equal_p (arg0, arg1, 0))
- return constant_boolean_node (0, type);
-
/* Fold (double)float1 CMP (double)float2 into float1 CMP float2. */
{
tree targ0 = strip_float_extensions (arg0);
|| ! FLOAT_TYPE_P (TREE_TYPE (@0))
|| ! HONOR_NANS (TYPE_MODE (TREE_TYPE (@0))))
{ constant_boolean_node (false, type); })))
+(for cmp (unle unge uneq)
+ (simplify
+ (cmp @0 @0)
+ { constant_boolean_node (true, type); }))
+(simplify
+ (ltgt @0 @0)
+ (if (!flag_trapping_math)
+ { constant_boolean_node (false, type); }))
/* Fold ~X op ~Y as Y op X. */
(for cmp (simple_comparison)
(ge (convert:st @0) { build_zero_cst (st); })
(lt (convert:st @0) { build_zero_cst (st); }))))))))))
+(for cmp (unordered ordered unlt unle ungt unge uneq ltgt)
+ /* If the second operand is NaN, the result is constant. */
+ (simplify
+ (cmp @0 REAL_CST@1)
+ (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
+ && (cmp != LTGT_EXPR || ! flag_trapping_math))
+ { constant_boolean_node (cmp == ORDERED_EXPR || code == LTGT_EXPR
+ ? false : true, type); })))
/* bool_var != 0 becomes bool_var. */
(simplify
- (ne @0 integer_zerop@1)
+ (ne @0 integer_zerop)
(if (TREE_CODE (TREE_TYPE (@0)) == BOOLEAN_TYPE
&& types_match (type, TREE_TYPE (@0)))
(non_lvalue @0)))
/* bool_var == 1 becomes bool_var. */
(simplify
- (eq @0 integer_onep@1)
+ (eq @0 integer_onep)
(if (TREE_CODE (TREE_TYPE (@0)) == BOOLEAN_TYPE
&& types_match (type, TREE_TYPE (@0)))
(non_lvalue @0)))
+/* Do not handle
+ bool_var == 0 becomes !bool_var or
+ bool_var != 1 becomes !bool_var
+ here because that only is good in assignment context as long
+ as we require a tcc_comparison in GIMPLE_CONDs where we'd
+ replace if (x == 0) with tem = ~x; if (tem != 0) which is
+ clearly less optimal and which we'll transform again in forwprop. */
/* Simplification of math builtins. */