diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr71055.c | 18 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 24 |
4 files changed, 52 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2332732..740a3f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2016-05-11 Richard Biener <rguenther@suse.de> + PR tree-optimization/71055 + * tree-ssa-sccvn.c (vn_reference_lookup_3): When native-interpreting + sth with precision not equal to access size verify we don't chop + off bits. + +2016-05-11 Richard Biener <rguenther@suse.de> + PR debug/71057 * dwarf2out.c (retry_incomplete_types): Set early_dwarf. (dwarf2out_finish): Move retry_incomplete_types call ... diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4f7f0f8..9170347 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2016-05-11 Richard Biener <rguenther@suse.de> + PR tree-optimization/71055 + * gcc.dg/torture/pr71055.c: New testcase. + +2016-05-11 Richard Biener <rguenther@suse.de> + PR debug/71057 * g++.dg/debug/pr71057.C: New testcase. diff --git a/gcc/testsuite/gcc.dg/torture/pr71055.c b/gcc/testsuite/gcc.dg/torture/pr71055.c new file mode 100644 index 0000000..7fe5a71 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71055.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ + +extern void abort (void); +union U { int i; _Bool b; char c; }; +void __attribute__((noinline,noclone)) +foo (union U *u) +{ + if (u->c != 0) + abort (); +} +int main() +{ + union U u; + u.i = 10; + u.b = 0; + foo (&u); + return 0; +} diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 6344117..1567fb9 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1907,14 +1907,34 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, buffer, sizeof (buffer)); if (len > 0) { - tree val = native_interpret_expr (vr->type, + tree type = vr->type; + /* Make sure to interpret in a type that has a range + covering the whole access size. */ + if (INTEGRAL_TYPE_P (vr->type) + && ref->size != TYPE_PRECISION (vr->type)) + type = build_nonstandard_integer_type (ref->size, + TYPE_UNSIGNED (type)); + tree val = native_interpret_expr (type, buffer + ((offset - offset2) / BITS_PER_UNIT), ref->size / BITS_PER_UNIT); + /* If we chop off bits because the types precision doesn't + match the memory access size this is ok when optimizing + reads but not when called from the DSE code during + elimination. */ + if (val + && type != vr->type) + { + if (! int_fits_type_p (val, vr->type)) + val = NULL_TREE; + else + val = fold_convert (vr->type, val); + } + if (val) return vn_reference_lookup_or_insert_for_pieces - (vuse, vr->set, vr->type, vr->operands, val); + (vuse, vr->set, vr->type, vr->operands, val); } } } |