+2004-07-11 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin_fputs): Don't bother converting the
+ return type to integer_type_node, as we've already checked that
+ the result will be ignored.
+
+ * tree-eh.c (tree_could_trap_p): Add support for -ftrapv such
+ that signed addition, subtraction, multiplication, division,
+ remainder, negation and absolute value may potentially trap.
+
+ * fold-const.c (fold_ignored_result): New function to strip
+ non-side-effecting tree nodes from an expression whose result
+ is ignored.
+ (fold_convert): Call fold_ignored_result when casting a value
+ to VOID_TYPE.
+ (omit_one_operand): Call fold_ignored_result on the "omitted"
+ operand when building a COMPOUND_EXPR.
+ (pedantic_omit_one_operand): Likewise.
+ * tree.h (fold_ignored_result): Prototype here.
+ * tree-ssa-ccp.c (ccp_fold_builtin): Call fold_ignored_result
+ when we're going to ignore the result.
+
2004-07-11 Richard Henderson <rth@redhat.com>
PR tree-opt/16383
abort ();
}
- return fold_convert (integer_type_node,
- build_function_call_expr (fn, arglist));
+ /* These optimizations are only performed when the result is ignored,
+ hence there's no need to cast the result to integer_type_node. */
+ return build_function_call_expr (fn, arglist);
}
static void
return fold (build1 (NOP_EXPR, type, arg));
}
else if (VOID_TYPE_P (type))
- return fold (build1 (CONVERT_EXPR, type, arg));
+ return fold (build1 (CONVERT_EXPR, type, fold_ignored_result (arg)));
abort ();
}
\f
tree t = fold_convert (type, result);
if (TREE_SIDE_EFFECTS (omitted))
- return build2 (COMPOUND_EXPR, type, omitted, t);
+ return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
return non_lvalue (t);
}
tree t = fold_convert (type, result);
if (TREE_SIDE_EFFECTS (omitted))
- return build2 (COMPOUND_EXPR, type, omitted, t);
+ return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
return pedantic_non_lvalue (t);
}
return build1 (INDIRECT_REF, type, t);
}
+/* Strip non-trapping, non-side-effecting tree nodes from an expression
+ whose result is ignored. The type of the returned tree need not be
+ the same as the original expression. */
+
+tree
+fold_ignored_result (tree t)
+{
+ if (!TREE_SIDE_EFFECTS (t))
+ return integer_zero_node;
+
+ for (;;)
+ switch (TREE_CODE_CLASS (TREE_CODE (t)))
+ {
+ case '1':
+ t = TREE_OPERAND (t, 0);
+ break;
+
+ case '2':
+ case '<':
+ if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
+ t = TREE_OPERAND (t, 0);
+ else if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0)))
+ t = TREE_OPERAND (t, 1);
+ else
+ return t;
+ break;
+
+ case 'e':
+ switch (TREE_CODE (t))
+ {
+ case COMPOUND_EXPR:
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
+ return t;
+ t = TREE_OPERAND (t, 0);
+ break;
+
+ case COND_EXPR:
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1))
+ || TREE_SIDE_EFFECTS (TREE_OPERAND (t, 2)))
+ return t;
+ t = TREE_OPERAND (t, 0);
+ break;
+
+ default:
+ return t;
+ }
+ break;
+
+ default:
+ return t;
+ }
+}
+
#include "gt-fold-const.h"
bool honor_nans = false;
bool honor_snans = false;
bool fp_operation = false;
+ bool honor_trapv = false;
tree t, base, idx;
if (TREE_CODE_CLASS (code) == '<'
honor_nans = flag_trapping_math && !flag_finite_math_only;
honor_snans = flag_signaling_nans != 0;
}
+ else if (INTEGRAL_TYPE_P (t) && TYPE_TRAP_SIGNED (t))
+ honor_trapv = true;
}
switch (code)
case ROUND_MOD_EXPR:
case TRUNC_MOD_EXPR:
case RDIV_EXPR:
- if (honor_snans)
+ if (honor_snans || honor_trapv)
return true;
if (fp_operation && flag_trapping_math)
return true;
case NEGATE_EXPR:
case ABS_EXPR:
case CONJ_EXPR:
- /* These operations don't trap even with floating point. */
+ /* These operations don't trap with floating point. */
+ if (honor_trapv)
+ return true;
+ return false;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ /* Any floating arithmetic may trap. */
+ if (fp_operation && flag_trapping_math)
+ return true;
+ if (honor_trapv)
+ return true;
return false;
default:
}
if (result && ignore)
- {
- /* STRIP_NOPS isn't strong enough -- it'll stop when we change modes,
- but given that we're ignoring the result, we don't care what type
- is being returned by the transformed function. */
- while (TREE_CODE (result) == NOP_EXPR
- || TREE_CODE (result) == CONVERT_EXPR
- || TREE_CODE (result) == NON_LVALUE_EXPR)
- result = TREE_OPERAND (result, 0);
- }
-
+ result = fold_ignored_result (result);
return result;
}
extern tree fold_initializer (tree);
extern tree fold_convert (tree, tree);
extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
+extern tree fold_ignored_result (tree);
extern tree fold_abs_const (tree, tree);
extern int force_fit_type (tree, int);