aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-08-23 09:57:05 +0200
committerRichard Biener <rguenther@suse.de>2021-08-23 11:53:15 +0200
commitad665deeafd31238b537139385e1e80b40c10e0c (patch)
tree5b0c5616fb3711b3393e31a5287aa248f657762e /gcc/tree-ssa-sccvn.c
parent70c7ab5c487f392e04907ce8f22eb454b8d3c4ff (diff)
downloadgcc-ad665deeafd31238b537139385e1e80b40c10e0c.zip
gcc-ad665deeafd31238b537139385e1e80b40c10e0c.tar.gz
gcc-ad665deeafd31238b537139385e1e80b40c10e0c.tar.bz2
tree-optimization/79334 - avoid PRE of possibly trapping array-ref
This replicates tree-eh.c in_array_bound_p into VNs vn_reference_may_trap to fix hoisting of a possibly trapping ARRAY_REF across a call that might not return. 2021-08-23 Richard Biener <rguenther@suse.de> PR tree-optimization/79334 * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Record a type also for COMPONENT_REFs. (vn_reference_may_trap): Check ARRAY_REF with constant index against the array domain. * gcc.dg/torture/pr79334-0.c: New testcase. * gcc.dg/torture/pr79334-1.c: Likewise.
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 82bd10b..bf87cee 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -914,9 +914,8 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
break;
case COMPONENT_REF:
/* The field decl is enough to unambiguously specify the field,
- a matching type is not necessary and a mismatching type
- is always a spurious difference. */
- temp.type = NULL_TREE;
+ so use its type here. */
+ temp.type = TREE_TYPE (TREE_OPERAND (ref, 1));
temp.op0 = TREE_OPERAND (ref, 1);
temp.op1 = TREE_OPERAND (ref, 2);
temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
@@ -5873,10 +5872,33 @@ vn_reference_may_trap (vn_reference_t ref)
return true;
break;
case ARRAY_RANGE_REF:
- case ARRAY_REF:
if (TREE_CODE (op->op0) == SSA_NAME)
return true;
break;
+ case ARRAY_REF:
+ {
+ if (TREE_CODE (op->op0) != INTEGER_CST)
+ return true;
+
+ /* !in_array_bounds */
+ tree domain_type = TYPE_DOMAIN (ref->operands[i+1].type);
+ if (!domain_type)
+ return true;
+
+ tree min = op->op1;
+ tree max = TYPE_MAX_VALUE (domain_type);
+ if (!min
+ || !max
+ || TREE_CODE (min) != INTEGER_CST
+ || TREE_CODE (max) != INTEGER_CST)
+ return true;
+
+ if (tree_int_cst_lt (op->op0, min)
+ || tree_int_cst_lt (max, op->op0))
+ return true;
+
+ break;
+ }
case MEM_REF:
/* Nothing interesting in itself, the base is separate. */
break;