On Fri, Aug 04, 2017 at 11:08:49AM +0200, Richard Biener wrote: > On Fri, Aug 4, 2017 at 10:38 AM, Marek Polacek <pola...@redhat.com> wrote: > > We were crashing because size_binop_loc got operands of different types: > > sizetype and ssizetype. Richi suggested performing the computation in > > offset_int which my patch tries to do. Unsure about the sdiv_trunc part, > > what do I use instead of EXACT_DIV_EXPR? > > Use wi::divmod_trunc and check for a zero remainder. If the remainder is not > zero we may not fold. > > Ok with that change.
Thanks, will commit this after the usual testing: 2017-08-04 Marek Polacek <pola...@redhat.com> PR middle-end/81695 * fold-const.c (fold_indirect_ref_1): For ((int *)&a + 4 -> a[1], perform the computation in offset_int. * gcc.dg/pr81695.c: New test. diff --git gcc/fold-const.c gcc/fold-const.c index ed6c289a64b..1f55bee8fc0 100644 --- gcc/fold-const.c +++ gcc/fold-const.c @@ -14106,14 +14106,21 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) && type == TREE_TYPE (op00type)) { tree type_domain = TYPE_DOMAIN (op00type); - tree min_val = size_zero_node; - if (type_domain && TYPE_MIN_VALUE (type_domain)) - min_val = TYPE_MIN_VALUE (type_domain); - op01 = size_binop_loc (loc, EXACT_DIV_EXPR, op01, - TYPE_SIZE_UNIT (type)); - op01 = size_binop_loc (loc, PLUS_EXPR, op01, min_val); - return build4_loc (loc, ARRAY_REF, type, op00, op01, - NULL_TREE, NULL_TREE); + tree min = TYPE_MIN_VALUE (type_domain); + if (min && TREE_CODE (min) == INTEGER_CST) + { + offset_int off = wi::to_offset (op01); + offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type)); + offset_int remainder; + off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder); + if (remainder == 0) + { + off = off + wi::to_offset (min); + op01 = wide_int_to_tree (sizetype, off); + return build4_loc (loc, ARRAY_REF, type, op00, op01, + NULL_TREE, NULL_TREE); + } + } } } } diff --git gcc/testsuite/gcc.dg/pr81695.c gcc/testsuite/gcc.dg/pr81695.c index e69de29bb2d..c3452580f1c 100644 --- gcc/testsuite/gcc.dg/pr81695.c +++ gcc/testsuite/gcc.dg/pr81695.c @@ -0,0 +1,11 @@ +/* PR middle-end/81695 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +int z[] = { }; + +int +main (void) +{ + __builtin_printf ("%d\n", *(z + 1)); +} Marek