aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 94263af..3c2c20a 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -7597,6 +7597,75 @@ commutative_ternary_tree_code (enum tree_code code)
return false;
}
+/* Returns true if CODE can overflow. */
+
+bool
+operation_can_overflow (enum tree_code code)
+{
+ switch (code)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case LSHIFT_EXPR:
+ /* Can overflow in various ways. */
+ return true;
+ case TRUNC_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ /* For INT_MIN / -1. */
+ return true;
+ case NEGATE_EXPR:
+ case ABS_EXPR:
+ /* For -INT_MIN. */
+ return true;
+ default:
+ /* These operators cannot overflow. */
+ return false;
+ }
+}
+
+/* Returns true if CODE operating on operands of type TYPE doesn't overflow, or
+ ftrapv doesn't generate trapping insns for CODE. */
+
+bool
+operation_no_trapping_overflow (tree type, enum tree_code code)
+{
+ gcc_checking_assert (ANY_INTEGRAL_TYPE_P (type));
+
+ /* We don't generate instructions that trap on overflow for complex or vector
+ types. */
+ if (!INTEGRAL_TYPE_P (type))
+ return true;
+
+ if (!TYPE_OVERFLOW_TRAPS (type))
+ return true;
+
+ switch (code)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case NEGATE_EXPR:
+ case ABS_EXPR:
+ /* These operators can overflow, and -ftrapv generates trapping code for
+ these. */
+ return false;
+ case TRUNC_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case LSHIFT_EXPR:
+ /* These operators can overflow, but -ftrapv does not generate trapping
+ code for these. */
+ return true;
+ default:
+ /* These operators cannot overflow. */
+ return true;
+ }
+}
+
namespace inchash
{