+ case TRUTH_NOT_EXPR:
+ /* The argument to invert_truthvalue must have Boolean type. */
+ if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
+ arg0 = fold_convert (boolean_type_node, arg0);
+
+ /* Note that the operand of this must be an int
+ and its values must be 0 or 1.
+ ("true" is a fixed value perhaps depending on the language,
+ but we don't handle values other than 1 correctly yet.) */
+ tem = invert_truthvalue (arg0);
+ /* Avoid infinite recursion. */
+ if (TREE_CODE (tem) == TRUTH_NOT_EXPR)
+ return t;
+ return fold_convert (type, tem);
+
+ case REALPART_EXPR:
+ if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
+ return t;
+ else if (TREE_CODE (arg0) == COMPLEX_EXPR)
+ return omit_one_operand (type, TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg0, 1));
+ else if (TREE_CODE (arg0) == COMPLEX_CST)
+ return TREE_REALPART (arg0);
+ else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
+ return fold (build2 (TREE_CODE (arg0), type,
+ fold (build1 (REALPART_EXPR, type,
+ TREE_OPERAND (arg0, 0))),
+ fold (build1 (REALPART_EXPR, type,
+ TREE_OPERAND (arg0, 1)))));
+ return t;
+
+ case IMAGPART_EXPR:
+ if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
+ return fold_convert (type, integer_zero_node);
+ else if (TREE_CODE (arg0) == COMPLEX_EXPR)
+ return omit_one_operand (type, TREE_OPERAND (arg0, 1),
+ TREE_OPERAND (arg0, 0));
+ else if (TREE_CODE (arg0) == COMPLEX_CST)
+ return TREE_IMAGPART (arg0);
+ else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
+ return fold (build2 (TREE_CODE (arg0), type,
+ fold (build1 (IMAGPART_EXPR, type,
+ TREE_OPERAND (arg0, 0))),
+ fold (build1 (IMAGPART_EXPR, type,
+ TREE_OPERAND (arg0, 1)))));
+ return t;
+
+ default:
+ return t;
+ } /* switch (code) */
+}
+
+/* Fold a ternary expression EXPR. Return the folded expression if
+ folding is successful. Otherwise, return the original
+ expression. */
+
+static tree
+fold_ternary (tree expr)
+{
+ const tree t = expr;
+ const tree type = TREE_TYPE (expr);
+ tree tem;
+ tree arg0 = NULL_TREE, arg1 = NULL_TREE;
+ enum tree_code code = TREE_CODE (t);
+ enum tree_code_class kind = TREE_CODE_CLASS (code);
+ int i;
+
+ gcc_assert (IS_EXPR_CODE_CLASS (kind)
+ && TREE_CODE_LENGTH (code) == 3);
+
+ /* For now, we iterate only twice even though we are handling
+ ternary expressions. This is because we haven't defined arg2
+ yet. */
+ for (i = 0; i < 2; i++)
+ {
+ tree op = TREE_OPERAND (t, i);
+
+ if (op == 0)
+ continue; /* Valid for CALL_EXPR, at least. */
+
+ /* Strip any conversions that don't change the mode. This is
+ safe for every expression, except for a comparison expression
+ because its signedness is derived from its operands. So, in
+ the latter case, only strip conversions that don't change the
+ signedness.
+
+ Note that this is done as an internal manipulation within the
+ constant folder, in order to find the simplest representation
+ of the arguments so that their form can be studied. In any
+ cases, the appropriate type conversions should be put back in
+ the tree that will get out of the constant folder. */
+ STRIP_NOPS (op);
+
+ if (i == 0)
+ arg0 = op;
+ else if (i == 1)
+ arg1 = op;
+ }
+
+ switch (code)
+ {
+ case COMPONENT_REF:
+ if (TREE_CODE (arg0) == CONSTRUCTOR
+ && ! type_contains_placeholder_p (TREE_TYPE (arg0)))
+ {
+ tree m = purpose_member (arg1, CONSTRUCTOR_ELTS (arg0));
+ if (m)
+ return TREE_VALUE (m);
+ }
+ return t;
+
+ case COND_EXPR:
+ /* Pedantic ANSI C says that a conditional expression is never an lvalue,
+ so all simple results must be passed through pedantic_non_lvalue. */
+ if (TREE_CODE (arg0) == INTEGER_CST)
+ {
+ tem = TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1));
+ /* Only optimize constant conditions when the selected branch
+ has the same type as the COND_EXPR. This avoids optimizing
+ away "c ? x : throw", where the throw has a void type. */
+ if (! VOID_TYPE_P (TREE_TYPE (tem))
+ || VOID_TYPE_P (type))
+ return pedantic_non_lvalue (tem);
+ return t;
+ }
+ if (operand_equal_p (arg1, TREE_OPERAND (t, 2), 0))
+ return pedantic_omit_one_operand (type, arg1, arg0);
+
+ /* If we have A op B ? A : C, we may be able to convert this to a
+ simpler expression, depending on the operation and the values
+ of B and C. Signed zeros prevent all of these transformations,
+ for reasons given above each one.
+
+ Also try swapping the arguments and inverting the conditional. */
+ if (COMPARISON_CLASS_P (arg0)
+ && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
+ arg1, TREE_OPERAND (arg0, 1))
+ && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
+ {
+ tem = fold_cond_expr_with_comparison (type, arg0,
+ TREE_OPERAND (t, 1),
+ TREE_OPERAND (t, 2));
+ if (tem)
+ return tem;
+ }
+
+ if (COMPARISON_CLASS_P (arg0)
+ && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (t, 2),
+ TREE_OPERAND (arg0, 1))
+ && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 2)))))
+ {
+ tem = invert_truthvalue (arg0);
+ if (COMPARISON_CLASS_P (tem))
+ {
+ tem = fold_cond_expr_with_comparison (type, tem,
+ TREE_OPERAND (t, 2),
+ TREE_OPERAND (t, 1));
+ if (tem)
+ return tem;
+ }
+ }
+
+ /* If the second operand is simpler than the third, swap them
+ since that produces better jump optimization results. */
+ if (tree_swap_operands_p (TREE_OPERAND (t, 1),
+ TREE_OPERAND (t, 2), false))
+ {
+ /* See if this can be inverted. If it can't, possibly because
+ it was a floating-point inequality comparison, don't do
+ anything. */
+ tem = invert_truthvalue (arg0);
+
+ if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
+ return fold (build3 (code, type, tem,
+ TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)));
+ }
+
+ /* Convert A ? 1 : 0 to simply A. */
+ if (integer_onep (TREE_OPERAND (t, 1))
+ && integer_zerop (TREE_OPERAND (t, 2))
+ /* If we try to convert TREE_OPERAND (t, 0) to our type, the
+ call to fold will try to move the conversion inside
+ a COND, which will recurse. In that case, the COND_EXPR
+ is probably the best choice, so leave it alone. */
+ && type == TREE_TYPE (arg0))
+ return pedantic_non_lvalue (arg0);
+
+ /* Convert A ? 0 : 1 to !A. This prefers the use of NOT_EXPR
+ over COND_EXPR in cases such as floating point comparisons. */
+ if (integer_zerop (TREE_OPERAND (t, 1))
+ && integer_onep (TREE_OPERAND (t, 2))
+ && truth_value_p (TREE_CODE (arg0)))
+ return pedantic_non_lvalue (fold_convert (type,
+ invert_truthvalue (arg0)));
+
+ /* A < 0 ? <sign bit of A> : 0 is simply (A & <sign bit of A>). */
+ if (TREE_CODE (arg0) == LT_EXPR
+ && integer_zerop (TREE_OPERAND (arg0, 1))
+ && integer_zerop (TREE_OPERAND (t, 2))
+ && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1)))
+ return fold_convert (type, fold (build2 (BIT_AND_EXPR,
+ TREE_TYPE (tem), tem, arg1)));
+
+ /* (A >> N) & 1 ? (1 << N) : 0 is simply A & (1 << N). A & 1 was
+ already handled above. */
+ if (TREE_CODE (arg0) == BIT_AND_EXPR
+ && integer_onep (TREE_OPERAND (arg0, 1))
+ && integer_zerop (TREE_OPERAND (t, 2))
+ && integer_pow2p (arg1))
+ {
+ tree tem = TREE_OPERAND (arg0, 0);
+ STRIP_NOPS (tem);
+ if (TREE_CODE (tem) == RSHIFT_EXPR
+ && TREE_CODE (TREE_OPERAND (tem, 1)) == INTEGER_CST
+ && (unsigned HOST_WIDE_INT) tree_log2 (arg1) ==
+ TREE_INT_CST_LOW (TREE_OPERAND (tem, 1)))
+ return fold (build2 (BIT_AND_EXPR, type,
+ TREE_OPERAND (tem, 0), arg1));
+ }
+
+ /* A & N ? N : 0 is simply A & N if N is a power of two. This
+ is probably obsolete because the first operand should be a
+ truth value (that's why we have the two cases above), but let's
+ leave it in until we can confirm this for all front-ends. */
+ if (integer_zerop (TREE_OPERAND (t, 2))
+ && TREE_CODE (arg0) == NE_EXPR
+ && integer_zerop (TREE_OPERAND (arg0, 1))
+ && integer_pow2p (arg1)
+ && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
+ && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
+ arg1, OEP_ONLY_CONST))
+ return pedantic_non_lvalue (fold_convert (type,
+ TREE_OPERAND (arg0, 0)));
+
+ /* Convert A ? B : 0 into A && B if A and B are truth values. */
+ if (integer_zerop (TREE_OPERAND (t, 2))
+ && truth_value_p (TREE_CODE (arg0))
+ && truth_value_p (TREE_CODE (arg1)))
+ return fold (build2 (TRUTH_ANDIF_EXPR, type, arg0, arg1));
+
+ /* Convert A ? B : 1 into !A || B if A and B are truth values. */
+ if (integer_onep (TREE_OPERAND (t, 2))
+ && truth_value_p (TREE_CODE (arg0))
+ && truth_value_p (TREE_CODE (arg1)))
+ {
+ /* Only perform transformation if ARG0 is easily inverted. */
+ tem = invert_truthvalue (arg0);
+ if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
+ return fold (build2 (TRUTH_ORIF_EXPR, type, tem, arg1));
+ }
+
+ /* Convert A ? 0 : B into !A && B if A and B are truth values. */
+ if (integer_zerop (arg1)
+ && truth_value_p (TREE_CODE (arg0))
+ && truth_value_p (TREE_CODE (TREE_OPERAND (t, 2))))
+ {
+ /* Only perform transformation if ARG0 is easily inverted. */
+ tem = invert_truthvalue (arg0);
+ if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
+ return fold (build2 (TRUTH_ANDIF_EXPR, type, tem,
+ TREE_OPERAND (t, 2)));
+ }
+
+ /* Convert A ? 1 : B into A || B if A and B are truth values. */
+ if (integer_onep (arg1)
+ && truth_value_p (TREE_CODE (arg0))
+ && truth_value_p (TREE_CODE (TREE_OPERAND (t, 2))))
+ return fold (build2 (TRUTH_ORIF_EXPR, type, arg0,
+ TREE_OPERAND (t, 2)));
+
+ return t;
+
+ case CALL_EXPR:
+ /* Check for a built-in function. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
+ && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0))
+ == FUNCTION_DECL)
+ && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
+ {
+ tree tmp = fold_builtin (t, false);
+ if (tmp)
+ return tmp;
+ }
+ return t;
+
+ default:
+ return t;
+ } /* switch (code) */
+}
+
+/* Perform constant folding and related simplification of EXPR.
+ The related simplifications include x*1 => x, x*0 => 0, etc.,
+ and application of the associative law.
+ NOP_EXPR conversions may be removed freely (as long as we
+ are careful not to change the type of the overall expression).
+ We cannot simplify through a CONVERT_EXPR, FIX_EXPR or FLOAT_EXPR,
+ but we can constant-fold them if they have constant operands. */
+
+#ifdef ENABLE_FOLD_CHECKING
+# define fold(x) fold_1 (x)
+static tree fold_1 (tree);
+static
+#endif
+tree
+fold (tree expr)
+{
+ const tree t = expr;
+ const tree type = TREE_TYPE (expr);
+ tree t1 = NULL_TREE;
+ tree tem;
+ tree arg0 = NULL_TREE, arg1 = NULL_TREE;
+ enum tree_code code = TREE_CODE (t);
+ enum tree_code_class kind = TREE_CODE_CLASS (code);
+
+ /* WINS will be nonzero when the switch is done
+ if all operands are constant. */
+ int wins = 1;
+
+ /* Return right away if a constant. */
+ if (kind == tcc_constant)
+ return t;
+
+ if (IS_EXPR_CODE_CLASS (kind))
+ {
+ switch (TREE_CODE_LENGTH (code))
+ {
+ case 1:
+ return fold_unary (expr);
+ case 3:
+ return fold_ternary (expr);
+ default:
+ break;
+ }
+ }
+
+ if (IS_EXPR_CODE_CLASS (kind))
+ {
+ int len = TREE_CODE_LENGTH (code);
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ tree op = TREE_OPERAND (t, i);
+ tree subop;
+
+ if (op == 0)
+ continue; /* Valid for CALL_EXPR, at least. */
+
+ /* Strip any conversions that don't change the mode. This is
+ safe for every expression, except for a comparison expression
+ because its signedness is derived from its operands. So, in
+ the latter case, only strip conversions that don't change the
+ signedness.
+
+ Note that this is done as an internal manipulation within the
+ constant folder, in order to find the simplest representation
+ of the arguments so that their form can be studied. In any
+ cases, the appropriate type conversions should be put back in
+ the tree that will get out of the constant folder. */
+ if (kind == tcc_comparison)
+ STRIP_SIGN_NOPS (op);
+ else
+ STRIP_NOPS (op);
+
+ if (TREE_CODE (op) == COMPLEX_CST)
+ subop = TREE_REALPART (op);
+ else
+ subop = op;
+
+ if (TREE_CODE (subop) != INTEGER_CST
+ && TREE_CODE (subop) != REAL_CST)
+ /* Note that TREE_CONSTANT isn't enough:
+ static var addresses are constant but we can't
+ do arithmetic on them. */
+ wins = 0;
+
+ if (i == 0)
+ arg0 = op;
+ else if (i == 1)
+ arg1 = op;
+ }
+ }
+
+ /* If this is a commutative operation, and ARG0 is a constant, move it
+ to ARG1 to reduce the number of tests below. */
+ if (commutative_tree_code (code)
+ && tree_swap_operands_p (arg0, arg1, true))
+ return fold (build2 (code, type, TREE_OPERAND (t, 1),
+ TREE_OPERAND (t, 0)));
+
+ /* Now WINS is set as described above,
+ ARG0 is the first operand of EXPR,
+ and ARG1 is the second operand (if it has more than one operand).
+
+ First check for cases where an arithmetic operation is applied to a
+ compound, conditional, or comparison operation. Push the arithmetic
+ operation inside the compound or conditional to see if any folding
+ can then be done. Convert comparison to conditional for this purpose.
+ The also optimizes non-constant cases that used to be done in
+ expand_expr.
+
+ Before we do that, see if this is a BIT_AND_EXPR or a BIT_IOR_EXPR,
+ one of the operands is a comparison and the other is a comparison, a
+ BIT_AND_EXPR with the constant 1, or a truth value. In that case, the
+ code below would make the expression more complex. Change it to a
+ TRUTH_{AND,OR}_EXPR. Likewise, convert a similar NE_EXPR to
+ TRUTH_XOR_EXPR and an EQ_EXPR to the inversion of a TRUTH_XOR_EXPR. */
+
+ if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
+ || code == EQ_EXPR || code == NE_EXPR)
+ && ((truth_value_p (TREE_CODE (arg0))
+ && (truth_value_p (TREE_CODE (arg1))
+ || (TREE_CODE (arg1) == BIT_AND_EXPR
+ && integer_onep (TREE_OPERAND (arg1, 1)))))
+ || (truth_value_p (TREE_CODE (arg1))
+ && (truth_value_p (TREE_CODE (arg0))
+ || (TREE_CODE (arg0) == BIT_AND_EXPR
+ && integer_onep (TREE_OPERAND (arg0, 1)))))))
+ {
+ tem = fold (build2 (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
+ : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
+ : TRUTH_XOR_EXPR,
+ type, fold_convert (boolean_type_node, arg0),
+ fold_convert (boolean_type_node, arg1)));
+
+ if (code == EQ_EXPR)
+ tem = invert_truthvalue (tem);
+
+ return tem;
+ }
+
+ if (TREE_CODE_CLASS (code) == tcc_comparison
+ && TREE_CODE (arg0) == COMPOUND_EXPR)
+ return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
+ fold (build2 (code, type, TREE_OPERAND (arg0, 1), arg1)));
+ else if (TREE_CODE_CLASS (code) == tcc_comparison
+ && TREE_CODE (arg1) == COMPOUND_EXPR)
+ return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
+ fold (build2 (code, type, arg0, TREE_OPERAND (arg1, 1))));
+ else if (TREE_CODE_CLASS (code) == tcc_binary
+ || TREE_CODE_CLASS (code) == tcc_comparison)
+ {
+ if (TREE_CODE (arg0) == COMPOUND_EXPR)
+ return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
+ fold (build2 (code, type, TREE_OPERAND (arg0, 1),
+ arg1)));
+ if (TREE_CODE (arg1) == COMPOUND_EXPR
+ && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
+ return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
+ fold (build2 (code, type,
+ arg0, TREE_OPERAND (arg1, 1))));
+
+ if (TREE_CODE (arg0) == COND_EXPR || COMPARISON_CLASS_P (arg0))
+ {
+ tem = fold_binary_op_with_conditional_arg (t, code, arg0, arg1,
+ /*cond_first_p=*/1);
+ if (tem != NULL_TREE)
+ return tem;
+ }
+
+ if (TREE_CODE (arg1) == COND_EXPR || COMPARISON_CLASS_P (arg1))
+ {
+ tem = fold_binary_op_with_conditional_arg (t, code, arg1, arg0,
+ /*cond_first_p=*/0);
+ if (tem != NULL_TREE)
+ return tem;
+ }
+ }
+
+ switch (code)
+ {
+ case CONST_DECL:
+ return fold (DECL_INITIAL (t));
+
+ case RANGE_EXPR:
+ if (TREE_CONSTANT (t) != wins)
+ {
+ tem = copy_node (t);
+ TREE_CONSTANT (tem) = wins;
+ TREE_INVARIANT (tem) = wins;
+ return tem;
+ }
+ return t;
+
+ case PLUS_EXPR:
+ /* A + (-B) -> A - B */
+ if (TREE_CODE (arg1) == NEGATE_EXPR)
+ return fold (build2 (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
+ /* (-A) + B -> B - A */
+ if (TREE_CODE (arg0) == NEGATE_EXPR