Bug 85164 - poly-int.h:845:5: runtime error: signed integer overflow
Summary: poly-int.h:845:5: runtime error: signed integer overflow
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: ---
Assignee: Richard Sandiford
URL:
Keywords:
Depends on:
Blocks: ubsan
  Show dependency treegraph
 
Reported: 2018-04-03 07:34 UTC by David Binderman
Modified: 2019-04-25 09:17 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-04-03 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Binderman 2018-04-03 07:34:40 UTC
For the following C code, in file bug425b.c

a[];
b;
c() {
  unsigned long d;
  b = a[d - 1 >> 3];
}

Compiled by gcc trunk revision 259004, compiled with undefined behaviour
sanitizer, does this:

$ ~/gcc/results/bin/gcc -c -O2 -w bug425b.c
../../trunk/gcc/poly-int.h:845:5: runtime error: signed integer overflow: 9223372036854775804 + 4 cannot be represented in type 'long int'
$ ~/gcc/results/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/home/dcb/gcc/results/bin/gcc
COLLECT_LTO_WRAPPER=/home/dcb/gcc/results.259004.ubsan/libexec/gcc/x86_64-pc-linux-gnu/8.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../trunk/configure --prefix=/home/dcb/gcc/results.259004.ubsan --with-build-config=bootstrap-ubsan --disable-multilib --disable-werror --enable-checking=df,extra,fold,rtl,yes --enable-languages=c,c++,fortran
Thread model: posix
gcc version 8.0.1 20180402 (experimental) (GCC) 
$
Comment 1 David Binderman 2018-08-13 09:31:02 UTC
Still going wrong. Here is another test case:

$ ~/gcc/results.263471.ubsan/bin/gcc -c -O2 bug456.c
../../trunk/gcc/poly-int.h:1941:12: runtime error: negation of -9223372036854775808 cannot be represented in type 'long int'; cast to an unsigned type to negate this value to itself
$ more bug456.c
int a;
long b;
void c() { b = -9223372036854775807L - 1 - a; }
$
Comment 2 Vittorio Zecca 2019-04-16 07:45:39 UTC
Still in trunk 270309.

Optimization at least -O1 needed to reproduce the bug.

/home/vitti/local/gcc-270309-undefined/bin/gcc -S gccerr70.c -O1
../../gcc/gcc/poly-int.h:845:5: runtime error: signed integer overflow: 9223372036854775804 + 4 cannot be represented in type 'long int'
Comment 3 David Binderman 2019-04-16 11:29:20 UTC
I'd be happy to help out with any testing of any speculative patch
for this bug.

I am surprised that more than 64 bits of precision are required.

Would a data type like float or double do the job ? Less precision,
more range.
Comment 4 Martin Liška 2019-04-17 08:36:29 UTC
For the 2 test-cases we reach these backtraces:

$ ./xgcc -B. test.c -O1
../../gcc/poly-int.h:1941:12: runtime error: negation of -9223372036854775808 cannot be represented in type 'long int'; cast to an unsigned type to negate this value to itself
    #0 0xc8bbdc in poly_result<poly_int_traits<long>::coeff_type, poly_int_traits<long>::coeff_type, poly_coeff_pair_traits<poly_int_traits<long>::coeff_type, poly_int_traits<long>::coeff_type>::result_kind>::type known_alignment<1u, long>(poly_int_pod<1u, long> const&) ../../gcc/poly-int.h:1941
    #1 0x3db9fdd in force_int_to_mode ../../gcc/combine.c:8949
    #2 0x3db8c5b in force_to_mode ../../gcc/combine.c:8802
    #3 0x3da45a8 in simplify_set ../../gcc/combine.c:6876
    #4 0x3d9f16d in combine_simplify_rtx ../../gcc/combine.c:6456
    #5 0x3d96712 in subst ../../gcc/combine.c:5727
    #6 0x3d950fa in subst ../../gcc/combine.c:5590
    #7 0x3d7ead4 in try_combine ../../gcc/combine.c:3420
    #8 0x3d6e699 in combine_instructions ../../gcc/combine.c:1306
    #9 0x3df4563 in rest_of_handle_combine ../../gcc/combine.c:15076
    #10 0x3df4702 in execute ../../gcc/combine.c:15121
    #11 0x1baf287 in execute_one_pass(opt_pass*) ../../gcc/passes.c:2487
    #12 0x1bafb1d in execute_pass_list_1 ../../gcc/passes.c:2573
    #13 0x1bafbd2 in execute_pass_list_1 ../../gcc/passes.c:2574
    #14 0x1bafc71 in execute_pass_list(function*, opt_pass*) ../../gcc/passes.c:2584
    #15 0xe52f0c in cgraph_node::expand() ../../gcc/cgraphunit.c:2198
    #16 0xe544d3 in expand_all_functions ../../gcc/cgraphunit.c:2336
    #17 0xe56b42 in symbol_table::compile() ../../gcc/cgraphunit.c:2687
    #18 0xe575a8 in symbol_table::finalize_compilation_unit() ../../gcc/cgraphunit.c:2865
    #19 0x2006fad in compile_file ../../gcc/toplev.c:481
    #20 0x200ea9b in do_compile ../../gcc/toplev.c:2205
    #21 0x200f0c9 in toplev::main(int, char**) ../../gcc/toplev.c:2340
    #22 0x438f452 in main ../../gcc/main.c:39
    #23 0x7ffff6e80b7a in __libc_start_main ../csu/libc-start.c:308
    #24 0x85f579 in _start (/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x85f579)

and

../../gcc/poly-int.h:845:5: runtime error: signed integer overflow: 9223372036854775804 + 4 cannot be represented in type 'long int'
    #0 0xc088f7 in poly_int<1u, poly_result<long, long, poly_coeff_pair_traits<long, long>::result_kind>::type> operator+<1u, long, long>(poly_int_pod<1u, long> const&, poly_int_pod<1u, long> const&) ../../gcc/poly-int.h:845
    #1 0x1e2e0f2 in rtx_addr_can_trap_p_1 ../../gcc/rtlanal.c:524
    #2 0x1e2ef7d in rtx_addr_can_trap_p_1 ../../gcc/rtlanal.c:659
    #3 0x1e2ec71 in rtx_addr_can_trap_p_1 ../../gcc/rtlanal.c:645
    #4 0x1e3e6fc in may_trap_p_1(rtx_def const*, unsigned int) ../../gcc/rtlanal.c:2836
    #5 0x1e3fc4c in may_trap_p_1(rtx_def const*, unsigned int) ../../gcc/rtlanal.c:2937
    #6 0x1e3fedf in may_trap_p(rtx_def const*) ../../gcc/rtlanal.c:2956
    #7 0x1cefd4b in copyprop_hardreg_forward_1 ../../gcc/regcprop.c:804
    #8 0x1cf6191 in cprop_hardreg_bb ../../gcc/regcprop.c:1320
    #9 0x1cf6da4 in execute ../../gcc/regcprop.c:1385
    #10 0x1baf287 in execute_one_pass(opt_pass*) ../../gcc/passes.c:2487
    #11 0x1bafb1d in execute_pass_list_1 ../../gcc/passes.c:2573
    #12 0x1bafbd2 in execute_pass_list_1 ../../gcc/passes.c:2574
    #13 0x1bafbd2 in execute_pass_list_1 ../../gcc/passes.c:2574
    #14 0x1bafc71 in execute_pass_list(function*, opt_pass*) ../../gcc/passes.c:2584
    #15 0xe52f0c in cgraph_node::expand() ../../gcc/cgraphunit.c:2198
    #16 0xe544d3 in expand_all_functions ../../gcc/cgraphunit.c:2336
    #17 0xe56b42 in symbol_table::compile() ../../gcc/cgraphunit.c:2687
    #18 0xe575a8 in symbol_table::finalize_compilation_unit() ../../gcc/cgraphunit.c:2865
    #19 0x2006fad in compile_file ../../gcc/toplev.c:481
    #20 0x200ea9b in do_compile ../../gcc/toplev.c:2205
    #21 0x200f0c9 in toplev::main(int, char**) ../../gcc/toplev.c:2340
    #22 0x438f452 in main ../../gcc/main.c:39
    #23 0x7ffff6e80b7a in __libc_start_main ../csu/libc-start.c:308
    #24 0x85f579 in _start (/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x85f579)
Comment 5 Jakub Jelinek 2019-04-17 10:51:26 UTC
The first above is on:
    case MINUS:
      /* If X is (minus C Y) where C's least set bit is larger than any bit
         in the mask, then we may replace with (neg Y).  */
      if (poly_int_rtx_p (XEXP (x, 0), &const_op0)
          && (unsigned HOST_WIDE_INT) known_alignment (const_op0) > mask)
and
template<unsigned int N, typename Ca>
inline POLY_BINARY_COEFF (Ca, Ca)
known_alignment (const poly_int_pod<N, Ca> &a)
{
  typedef POLY_BINARY_COEFF (Ca, Ca) C;
  C r = a.coeffs[0];
  for (unsigned int i = 1; i < N; ++i)
    r |= a.coeffs[i];
  return r & -r;
}

The poly_int* stuff makes this much harder to fix, it is unclear if there is some way to get the unsigned type for the C type and use that as r & -(Cuns) r;
to avoid the UB, and there is no poly_uint_rtx_p or something to request poly_uint64 from the rtx.  Richard?

The second one is
          return (!known_size_p (decl_size) || known_eq (decl_size, 0)
                  ? maybe_ne (offset, 0)
                  : maybe_gt (offset + size, decl_size));
and again, both offset and size are poly_int64, not sure how can one reinterpret cast that to poly_uint64 for the operation and then cast back to poly_int64.
But in that case also if we shouldn't punt on the overflow somehow.
Comment 6 Richard Sandiford 2019-04-17 15:50:24 UTC
(In reply to Jakub Jelinek from comment #5)
> The first above is on:
>     case MINUS:
>       /* If X is (minus C Y) where C's least set bit is larger than any bit
>          in the mask, then we may replace with (neg Y).  */
>       if (poly_int_rtx_p (XEXP (x, 0), &const_op0)
>           && (unsigned HOST_WIDE_INT) known_alignment (const_op0) > mask)
> and
> template<unsigned int N, typename Ca>
> inline POLY_BINARY_COEFF (Ca, Ca)
> known_alignment (const poly_int_pod<N, Ca> &a)
> {
>   typedef POLY_BINARY_COEFF (Ca, Ca) C;
>   C r = a.coeffs[0];
>   for (unsigned int i = 1; i < N; ++i)
>     r |= a.coeffs[i];
>   return r & -r;
> }
> 
> The poly_int* stuff makes this much harder to fix, it is unclear if there is
> some way to get the unsigned type for the C type and use that as r & -(Cuns)
> r;
> to avoid the UB, and there is no poly_uint_rtx_p or something to request
> poly_uint64 from the rtx.  Richard?

Changing:

    (unsigned HOST_WIDE_INT) known_alignment (const_op0)

to:

    known_alignment (poly_uint64 (const_op0))

should work.

> 
> The second one is
>           return (!known_size_p (decl_size) || known_eq (decl_size, 0)
>                   ? maybe_ne (offset, 0)
>                   : maybe_gt (offset + size, decl_size));
> and again, both offset and size are poly_int64, not sure how can one
> reinterpret cast that to poly_uint64 for the operation and then cast back to
> poly_int64.

Normal casts between poly_X and poly_Y work if casts between X and Y work.

> But in that case also if we shouldn't punt on the overflow somehow.

I guess using known_subrange_p would do that.
Comment 7 Jakub Jelinek 2019-04-17 16:10:44 UTC
(In reply to rsandifo@gcc.gnu.org from comment #6)

Thanks for handling this.

> > template<unsigned int N, typename Ca>
> > inline POLY_BINARY_COEFF (Ca, Ca)
> > known_alignment (const poly_int_pod<N, Ca> &a)
> > {
> >   typedef POLY_BINARY_COEFF (Ca, Ca) C;
> >   C r = a.coeffs[0];
> >   for (unsigned int i = 1; i < N; ++i)
> >     r |= a.coeffs[i];
> >   return r & -r;
> > }
> > 
> > The poly_int* stuff makes this much harder to fix, it is unclear if there is
> > some way to get the unsigned type for the C type and use that as r & -(Cuns)
> > r;
> > to avoid the UB, and there is no poly_uint_rtx_p or something to request
> > poly_uint64 from the rtx.  Richard?
> 
> Changing:
> 
>     (unsigned HOST_WIDE_INT) known_alignment (const_op0)
> 
> to:
> 
>     known_alignment (poly_uint64 (const_op0))
> 
> should work.

That will handle this specific case, I was just hoping that for known_alignment we could fix all the cases that could be called on poly_int64.  For HOST_WIDE_INT_MIN, do we want known_alignment to return HOST_WIDE_INT_MIN or something different?  It is maximum alignment admittedly only if we are treating the result as unsigned.  Or shall we in known_alignment assert or compile time assert that it is unsigned and fix all the users?
Comment 8 Richard Sandiford 2019-04-17 16:15:41 UTC
(In reply to Jakub Jelinek from comment #7)
> (In reply to rsandifo@gcc.gnu.org from comment #6)
> 
> Thanks for handling this.
> 
> > > template<unsigned int N, typename Ca>
> > > inline POLY_BINARY_COEFF (Ca, Ca)
> > > known_alignment (const poly_int_pod<N, Ca> &a)
> > > {
> > >   typedef POLY_BINARY_COEFF (Ca, Ca) C;
> > >   C r = a.coeffs[0];
> > >   for (unsigned int i = 1; i < N; ++i)
> > >     r |= a.coeffs[i];
> > >   return r & -r;
> > > }
> > > 
> > > The poly_int* stuff makes this much harder to fix, it is unclear if there is
> > > some way to get the unsigned type for the C type and use that as r & -(Cuns)
> > > r;
> > > to avoid the UB, and there is no poly_uint_rtx_p or something to request
> > > poly_uint64 from the rtx.  Richard?
> > 
> > Changing:
> > 
> >     (unsigned HOST_WIDE_INT) known_alignment (const_op0)
> > 
> > to:
> > 
> >     known_alignment (poly_uint64 (const_op0))
> > 
> > should work.
> 
> That will handle this specific case, I was just hoping that for
> known_alignment we could fix all the cases that could be called on
> poly_int64.  For HOST_WIDE_INT_MIN, do we want known_alignment to return
> HOST_WIDE_INT_MIN or something different?  It is maximum alignment
> admittedly only if we are treating the result as unsigned.  Or shall we in
> known_alignment assert or compile time assert that it is unsigned and fix
> all the users?

A compile-time assert sounds good.  Will try that on top to see how
invasive it ends up being.  (Shouldn't be too bad, since there aren't
many callers.)
Comment 9 Richard Sandiford 2019-04-18 12:30:29 UTC
Author: rsandifo
Date: Thu Apr 18 12:29:56 2019
New Revision: 270442

URL: https://gcc.gnu.org/viewcvs?rev=270442&root=gcc&view=rev
Log:
Fix two ubsan failures (PR85164)

Two fixes for UB when handling very large offsets.  The calculation in
force_int_to_mode would have been correct if signed integers used modulo
arithmetic, so just switch to unsigned types.  The calculation in
rtx_addr_can_trap_p_1 didn't handle overflow properly, so switch to
known_subrange_p instead (which is supposed to handle all cases).

2019-04-18  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	PR middle-end/85164
	* combine.c (force_int_to_mode): Cast the argument rather than
	the result of known_alignment.
	* rtlanal.c (rtx_addr_can_trap_p_1): Use known_subrange_p.

gcc/testsuite/
	PR middle-end/85164
	* gcc.dg/pr85164-1.c, gcc.dg/pr85164-2.c: New tests.

Added:
    trunk/gcc/testsuite/gcc.dg/pr85164-1.c
    trunk/gcc/testsuite/gcc.dg/pr85164-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/rtlanal.c
    trunk/gcc/testsuite/ChangeLog
Comment 10 Richard Sandiford 2019-04-18 12:31:09 UTC
Author: rsandifo
Date: Thu Apr 18 12:30:36 2019
New Revision: 270443

URL: https://gcc.gnu.org/viewcvs?rev=270443&root=gcc&view=rev
Log:
Fix UB in int_const_binop

When testing PR 85164, the baseline bootstrap-ubsan results had
a lot of failures from int_const_binop.  This is because with the
new overflow handling we can sometimes do:

      poly_res = res;

on an uninitialised res.

2019-04-18  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* fold-const.c (int_const_binop): Return early on failure.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/fold-const.c
Comment 11 Vittorio Zecca 2019-04-19 07:11:05 UTC
After applying your fixes I still have overflow compiling the following

// Must be compiled with nonzero optimization
//../../gcc/gcc/poly-int.h:1095:5: runtime error: signed integer
overflow: 9223372036854775807 * 8 cannot be represented in type 'long
int'
// 87042
const char a[] = {};
int b() { '\0' == a[9223372036854775807]; }

../../gcc/gcc/poly-int.h:1095:5: runtime error: signed integer
overflow: 9223372036854775807 * 8 cannot be represented in type 'long
int'

Remember must be compiled with nonzero optimization
Comment 12 Vittorio Zecca 2019-04-19 15:43:52 UTC
Here are two more test cases with undefined behaviour in poly-int.h

Must be compiled with nonzero optimization

cat gccerr73.c
// must be compiled with nonzero optimization
// ../../gcc/gcc/poly-int.h:753:21: runtime error: signed integer
overflow: -5621332293356458048 * 8 cannot be represented in type 'long
int'
int a[4];
void f()
{
  long int b = 7818038963515661296;
  a[0xA699ECD2C348A3A0] = a[b];
}


[vitti cc]$cat gccerr74.c
// Must be compiled with nonzero optimization
// ../../gcc/gcc/poly-int.h:944:5: runtime error: signed integer
overflow: 162675373468811328 - -9060696663385964544 cannot be
represented in type 'long int'
long b[1][9];
typedef long V __attribute__((vector_size (16), may_alias));

void
foo ()
{
  V *c = (V *) ((char *) b + -9060696663385964544);
  *c = (V) { 1, 1 };
  long __attribute__((may_alias)) *d = (long *) ((char *) b +
162675373468811328);
  *d = 1;
}
Comment 13 Martin Liška 2019-04-23 07:37:42 UTC
Can you please use:
$ export UBSAN_OPTIONS="print_stacktrace=1"

so that we see the complete back-trace? Thanks.
Comment 14 Richard Sandiford 2019-04-23 08:09:16 UTC
Yeah, the patch I committed fixed two separate instances of
undefined overflow, but I think there are a lot more left.
The testsuite results with bootstrap-ubsan show a lot of failures
generally, so the compiler isn't UB-free even for our existing tests.

I fixed another instance in r85164 that was unrelated to the testcases
in this PR, so if you're just applying the patches locally, it'd be worth
trying that as well.

Could you open separate PRs for the new tests?  We could perhaps
have a meta-bug for ubsan failures too, if we don't already.
Comment 15 Martin Liška 2019-04-23 08:10:46 UTC
> 
> Could you open separate PRs for the new tests?  We could perhaps
> have a meta-bug for ubsan failures too, if we don't already.

We do have one ('ubsan' alias name):
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63426
Comment 16 Vittorio Zecca 2019-04-23 12:38:23 UTC
On Saturday afternoon I had a power failure that probably damaged my disk,
so I cannot help you now.
Comment 17 Martin Liška 2019-04-23 12:49:20 UTC
> Could you open separate PRs for the new tests?  We could perhaps
> have a meta-bug for ubsan failures too, if we don't already.

I did so: PR90213 and PR90214.
Comment 18 David Binderman 2019-04-24 10:46:21 UTC
(In reply to rsandifo@gcc.gnu.org from comment #14)
> Yeah, the patch I committed fixed two separate instances of
> undefined overflow, but I think there are a lot more left.

Excellent results so far, but I have new data on remaining
runtime errors.

I tried all the C code in the testsuite with a ubsan
version of gcc trunk 270500. I used compiler flags -g -O3 -march=native -Wall.

I got 26 runtime errors, of which 20 are poly-int.h

C++ and fortran remain untested. I'll get to those soon.
Of the C errors, the 6 that aren't poly-int.h, I will report on
in other bug reports.

Of the 20 runtime errors from poly-int.h, they are produced
by this list of C source code files:

./c-c++-common/Warray-bounds-2.c
./c-c++-common/Warray-bounds.c
./gcc.dg/strlenopt-55.c
./gcc.dg/torture/pr84811.c
./gcc.dg/torture/pr84929.c
./gcc.dg/Warray-bounds-22.c
./gcc.dg/Warray-bounds-30.c
./gcc.dg/Warray-bounds-31.c

Most of these are array bounds. I'll find out stack backtraces for
each of these.
Comment 19 David Binderman 2019-04-24 11:00:33 UTC
For ./c-c++-common/Warray-bounds-2.c

../../trunk/gcc/poly-int.h:1107:5: runtime error: signed integer overflow: 8 * -9223372036854775796 cannot be represented in type 'long int'
    #0 0x2ddd587 in poly_int<1u, poly_result<if_nonpoly<int, int, poly_int_traits<int>::is_poly>::type, long, poly_coeff_pair_traits<if_nonpoly<int, int, poly_int_traits<int>::is_poly>::type, long>::result_kind>::type> operator*<1u, int, long>(int const&, poly_int_pod<1u, long> const&) ../../trunk/gcc/poly-int.h:1107
    #1 0x2ddd587 in ao_ref_init_from_ptr_and_size(ao_ref*, tree_node*, tree_node*) ../../trunk/gcc/tree-ssa-alias.c:703
    #2 0x2ea1f49 in initialize_ao_ref_for_dse ../../trunk/gcc/tree-ssa-dse.c:106
    #3 0x2ea1f49 in initialize_ao_ref_for_dse ../../trunk/gcc/tree-ssa-dse.c:91
    #4 0x2ea784b in dse_dom_walker::dse_optimize_stmt(gimple_stmt_iterator*) ../../trunk/gcc/tree-ssa-dse.c:851

For ./c-c++-common/Warray-bounds.c

../../trunk/gcc/poly-int.h:715:21: runtime error: signed integer overflow: 9223372036854775804 + 4 cannot be represented in type 'long int'
    #0 0x318ecb2 in poly_int<1u, long>& poly_int<1u, long>::operator+=<long>(poly_int_pod<1u, long> const&) ../../trunk/gcc/poly-int.h:715
    #1 0x318ecb2 in vn_reference_compute_hash ../../trunk/gcc/tree-ssa-sccvn.c:657
    #2 0x31b26b5 in vn_reference_lookup(tree_node*, tree_node*, vn_lookup_kind, vn_reference_s**, bool) ../../trunk/gcc/tree-ssa-sccvn.c:2714
    #3 0x31ea070 in visit_reference_op_load ../../trunk/gcc/tree-ssa-sccvn.c:4091
    #4 0x31ea070 in visit_stmt ../../trunk/gcc/tree-ssa-sccvn.c:4509

For /gcc.dg/strlenopt-55.c

../../trunk/gcc/poly-int.h:1095:5: runtime error: signed integer overflow: 9223372036854775805 * 8 cannot be represented in type 'long int'
    #0 0x31917e4 in poly_int<1u, poly_result<long, if_nonpoly<int, int, poly_int_traits<int>::is_poly>::type, poly_coeff_pair_traits<long, if_nonpoly<int, int, poly_int_traits<int>::is_poly>::type>::result_kind>::type> operator*<1u, long, int>(poly_int_pod<1u, long> const&, int const&) ../../trunk/gcc/poly-int.h:1095
    #1 0x31917e4 in fully_constant_vn_reference_p(vn_reference_s*) ../../trunk/gcc/tree-ssa-sccvn.c:1485
    #2 0x31b26c3 in vn_reference_lookup(tree_node*, tree_node*, vn_lookup_kind, vn_reference_s**, bool) ../../trunk/gcc/tree-ssa-sccvn.c:2715
    #3 0x31ea070 in visit_reference_op_load ../../trunk/gcc/tree-ssa-sccvn.c:4091
    #4 0x31ea070 in visit_stmt ../../trunk/gcc/tree-ssa-sccvn.c:4509

For ./gcc.dg/torture/pr84811.c

../../trunk/gcc/cse.c:2215:34: runtime error: signed integer overflow: 162675373468811328 - -9060696663385964544 cannot be represented in type 'long int'
    #0 0x4e5f416 in use_related_value ../../trunk/gcc/cse.c:2215
    #1 0x4e5f416 in cse_insn ../../trunk/gcc/cse.c:4877
    #2 0x4e60b7e in cse_extended_basic_block ../../trunk/gcc/cse.c:6662
    #3 0x4e60b7e in cse_main ../../trunk/gcc/cse.c:6841
    #4 0x4e680ee in rest_of_handle_cse2 ../../trunk/gcc/cse.c:7743


For /gcc.dg/torture/pr84929.c

../../trunk/gcc/poly-int.h:753:21: runtime error: signed integer overflow: -5621332293356458048 * 8 cannot be represented in type 'long int'
    #0 0x1929e14 in if_nonpoly<int, poly_int<1u, long>, poly_int_traits<int>::is_poly>::type& poly_int<1u, long>::operator*=<int>(int const&) ../../trunk/gcc/poly-int.h:753
    #1 0x1929e14 in fold_const_aggregate_ref_1(tree_node*, tree_node* (*)(tree_node*)) ../../trunk/gcc/gimple-fold.c:6992
    #2 0x192b422 in gimple_fold_stmt_to_constant_1(gimple*, tree_node* (*)(tree_node*), tree_node* (*)(tree_node*)) ../../trunk/gcc/gimple-fold.c:6426
    #3 0x2e1ab24 in ccp_fold ../../trunk/gcc/tree-ssa-ccp.c:1257
    #4 0x2e1ab24 in evaluate_stmt ../../trunk/gcc/tree-ssa-ccp.c:1785

For ./gcc.dg/Warray-bounds-22.c

../../trunk/gcc/poly-int.h:1095:5: runtime error: signed integer overflow: 9223372036854775807 * 8 cannot be represented in type 'long int'
    #0 0xf85e20 in poly_int<1u, poly_result<long, if_nonpoly<int, int, poly_int_traits<int>::is_poly>::type, poly_coeff_pair_traits<long, if_nonpoly<int, int, poly_int_traits<int>::is_poly>::type>::result_kind>::type> operator*<1u, long, int>(poly_int_pod<1u, long> const&, int const&) ../../trunk/gcc/poly-int.h:1095
    #1 0xf85e20 in get_object_alignment_2 ../../trunk/gcc/builtins.c:344
    #2 0xf86d9d in get_object_alignment_1(tree_node*, unsigned int*, unsigned long*) ../../trunk/gcc/builtins.c:394
    #3 0xf86d9d in get_object_alignment(tree_node*) ../../trunk/gcc/builtins.c:405
    #4 0x1690d75 in expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) ../../trunk/gcc/expr.c:10343

For ./gcc.dg/Warray-bounds-30.c

../../trunk/gcc/cse.c:2215:34: runtime error: signed integer overflow: 0 - -9223372036854775808 cannot be represented in type 'long int'
    #0 0x4e5f416 in use_related_value ../../trunk/gcc/cse.c:2215
    #1 0x4e5f416 in cse_insn ../../trunk/gcc/cse.c:4877
    #2 0x4e60b7e in cse_extended_basic_block ../../trunk/gcc/cse.c:6662
    #3 0x4e60b7e in cse_main ../../trunk/gcc/cse.c:6841
    #4 0x4e67ef5 in rest_of_handle_cse ../../trunk/gcc/cse.c:7678

For ./gcc.dg/Warray-bounds-31.c

../../trunk/gcc/poly-int.h:1095:5: runtime error: signed integer overflow: -9223372036854775799 * 8 cannot be represented in type 'long int'
    #0 0x31917e4 in poly_int<1u, poly_result<long, if_nonpoly<int, int, poly_int_traits<int>::is_poly>::type, poly_coeff_pair_traits<long, if_nonpoly<int, int, poly_int_traits<int>::is_poly>::type>::result_kind>::type> operator*<1u, long, int>(poly_int_pod<1u, long> const&, int const&) ../../trunk/gcc/poly-int.h:1095
    #1 0x31917e4 in fully_constant_vn_reference_p(vn_reference_s*) ../../trunk/gcc/tree-ssa-sccvn.c:1485
    #2 0x31b26c3 in vn_reference_lookup(tree_node*, tree_node*, vn_lookup_kind, vn_reference_s**, bool) ../../trunk/gcc/tree-ssa-sccvn.c:2715
    #3 0x31ea070 in visit_reference_op_load ../../trunk/gcc/tree-ssa-sccvn.c:4091
    #4 0x31ea070 in visit_stmt ../../trunk/gcc/tree-ssa-sccvn.c:4509
Comment 20 Richard Sandiford 2019-04-24 12:20:26 UTC
> Most of these are array bounds. I'll find out stack backtraces for
> each of these.

Thanks for the testing.  Could you open new PRs for the new backtraces?
These are really independent bugs, and it'd be useful to keep this PR
specific to the two problems fixed in r270442.

> I got 26 runtime errors, of which 20 are poly-int.h

FWIW, whether something occurs in poly-int.h or not isn't usually
that relevant.  A lot of arithmetic that used to be open-coded now
goes through functions in poly-int.h, so it tends to show up a lot
as the immediate point of failure.  But whether the operation triggers
UB is usually determined by the operation being done (i.e. by the
caller) rather than the way poly-int.h implements it.  On x86 targets,
what poly-int.h does is usually the same as what the original pre-poly-int
code did.

This was the case in both of the bugs fixed in r270442 for example.
Comment 21 David Binderman 2019-04-25 09:17:50 UTC
(In reply to rsandifo@gcc.gnu.org from comment #20)
> Thanks for the testing.  

You are welcome.

> Could you open new PRs for the new backtraces?

Done. Most of them were already mentioned in bugzilla, but for
the rest, I have raised 90241, 90242 and 90244.

> But whether the operation triggers
> UB is usually determined by the operation being done (i.e. by the
> caller) rather than the way poly-int.h implements it.  

Thanks for the explanation. It is a lot clearer now.