summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index e40681f9355..78af47ed5eb 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -3072,3 +3072,50 @@ sort_vuses_heap (VEC (tree,heap) *vuses)
sizeof (tree),
operand_build_cmp);
}
+
+
+/* Return true if the nary operation NARY may trap. This is a copy
+ of stmt_could_throw_1_p adjusted to the SCCVN IL. */
+
+bool
+vn_nary_may_trap (vn_nary_op_t nary)
+{
+ tree type;
+ tree rhs2;
+ bool honor_nans = false;
+ bool honor_snans = false;
+ bool fp_operation = false;
+ bool honor_trapv = false;
+ bool handled, ret;
+ unsigned i;
+
+ if (TREE_CODE_CLASS (nary->opcode) == tcc_comparison
+ || TREE_CODE_CLASS (nary->opcode) == tcc_unary
+ || TREE_CODE_CLASS (nary->opcode) == tcc_binary)
+ {
+ type = nary->type;
+ fp_operation = FLOAT_TYPE_P (type);
+ if (fp_operation)
+ {
+ honor_nans = flag_trapping_math && !flag_finite_math_only;
+ honor_snans = flag_signaling_nans != 0;
+ }
+ else if (INTEGRAL_TYPE_P (type)
+ && TYPE_OVERFLOW_TRAPS (type))
+ honor_trapv = true;
+ }
+ rhs2 = nary->op[1];
+ ret = operation_could_trap_helper_p (nary->opcode, fp_operation,
+ honor_trapv,
+ honor_nans, honor_snans, rhs2,
+ &handled);
+ if (handled
+ && ret)
+ return true;
+
+ for (i = 0; i < nary->length; ++i)
+ if (tree_could_trap_p (nary->op[i]))
+ return true;
+
+ return false;
+}