Re: [PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044).
On 11/15/2017 12:31 AM, Martin Liška wrote: > On 11/08/2017 05:31 PM, Jeff Law wrote: >> I don't see an updated patch in this thread? THe last message I see is >> this one where you indicate you're going to tweak the patch and re-test. >> >> Jeff > Yes, I tweaked and tested following patch. > > Martin > > > 0001-Fix-UBSAN-errors-in-dse.c-PR-rtl-optimization-82044.patch > > > From a369ac78b887e219a375e17d6817c1f744e71779 Mon Sep 17 00:00:00 2001 > From: marxin > Date: Thu, 19 Oct 2017 13:38:01 +0200 > Subject: [PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044). > > gcc/ChangeLog: > > 2017-10-19 Martin Liska > > PR rtl-optimization/82044 > PR tree-optimization/82042 > * dse.c (check_mem_read_rtx): Check for overflow. OK. jeff
Re: [PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044).
On 11/08/2017 05:31 PM, Jeff Law wrote: > I don't see an updated patch in this thread? THe last message I see is > this one where you indicate you're going to tweak the patch and re-test. > > Jeff Yes, I tweaked and tested following patch. Martin >From a369ac78b887e219a375e17d6817c1f744e71779 Mon Sep 17 00:00:00 2001 From: marxin Date: Thu, 19 Oct 2017 13:38:01 +0200 Subject: [PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044). gcc/ChangeLog: 2017-10-19 Martin Liska PR rtl-optimization/82044 PR tree-optimization/82042 * dse.c (check_mem_read_rtx): Check for overflow. --- gcc/dse.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/gcc/dse.c b/gcc/dse.c index 563ca9f56f3..f6d5e6e6fe2 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -1981,6 +1981,12 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) else width = GET_MODE_SIZE (GET_MODE (mem)); + if (offset > HOST_WIDE_INT_MAX - width) +{ + clear_rhs_from_active_local_stores (); + return; +} + read_info = read_info_type_pool.allocate (); read_info->group_id = group_id; read_info->mem = mem; -- 2.14.3
Re: [PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044).
On 11/02/2017 07:15 AM, Martin Liška wrote: > PING^1 I don't see an updated patch in this thread? THe last message I see is this one where you indicate you're going to tweak the patch and re-test. Jeff > > On 10/19/2017 01:36 PM, Martin Liška wrote: >> On 09/20/2017 10:15 AM, Jakub Jelinek wrote: >>> On Wed, Sep 20, 2017 at 09:50:32AM +0200, Martin Liška wrote: Hello. Following patch handles UBSAN (overflow) in dce.c. >>> >>> dse.c ;) >>> --- a/gcc/dse.c +++ b/gcc/dse.c @@ -929,7 +929,9 @@ set_usage_bits (group_info *group, HOST_WIDE_INT offset, HOST_WIDE_INT width, { HOST_WIDE_INT i; bool expr_escapes = can_escape (expr); - if (offset > -MAX_OFFSET && offset + width < MAX_OFFSET) + if (offset > -MAX_OFFSET + && offset < MAX_OFFSET + && offset + width < MAX_OFFSET) >>> >>> This can still overflow if width is close to HOST_WIDE_INT_MAX. >>> Anyway, I don't remember this code too much, but wonder if either offset or >>> width or their sum is outside of the -MAX_OFFSET, MAX_OFFSET range if we >>> still don't want to record usage bits at least in the intersection of >>> -MAX_OFFSET, MAX_OFFSET and offset, offset + width (the latter performed >>> with infinite precision; though, if record_store is changed as suggested >>> below, offset + width shouldn't overflow). >>> for (i=offset; i>>>{ bitmap store1; @@ -1536,7 +1538,11 @@ record_store (rtx body, bb_info_t bb_info) } store_info->group_id = group_id; store_info->begin = offset; - store_info->end = offset + width; + if (offset > HOST_WIDE_INT_MAX - width) +store_info->end = HOST_WIDE_INT_MAX; + else +store_info->end = offset + width; >>> >>> If offset + width overflows, I think we risk wrong-code by doing this, plus >>> there are 3 other offset + width computations earlier in record_store >>> before we reach this. I think instead we should treat such cases as wild >>> stores early, i.e.: >>>if (!canon_address (mem, &group_id, &offset, &base)) >>> { >>>clear_rhs_from_active_local_stores (); >>>return 0; >>> } >>> >>>if (GET_MODE (mem) == BLKmode) >>> width = MEM_SIZE (mem); >>>else >>> width = GET_MODE_SIZE (GET_MODE (mem)); >>> >>> + if (offset > HOST_WIDE_INT_MAX - width) >>> +{ >>> + clear_rhs_from_active_local_stores (); >>> + return 0; >>> +} >>> >>> or so. >>> + store_info->is_set = GET_CODE (body) == SET; store_info->rhs = rhs; store_info->const_rhs = const_rhs; @@ -1976,6 +1982,14 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) return; } + if (offset > MAX_OFFSET) +{ + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " reaches MAX_OFFSET.\n"); + add_wild_read (bb_info); + return; +} + >> >> Hi. >> >> The later one works for me. I'm going to regtest that. >> >> Ready after it survives regression tests? >> >> Thanks, >> Martin >> >>> >>> Is offset > MAX_OFFSET really problematic (and not just the width != -1 && >>> offset + width overflowing case)? >>> if (GET_MODE (mem) == BLKmode) width = -1; else >>> >>> >>> Jakub >>> >> >
Re: [PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044).
PING^1 On 10/19/2017 01:36 PM, Martin Liška wrote: > On 09/20/2017 10:15 AM, Jakub Jelinek wrote: >> On Wed, Sep 20, 2017 at 09:50:32AM +0200, Martin Liška wrote: >>> Hello. >>> >>> Following patch handles UBSAN (overflow) in dce.c. >> >> dse.c ;) >> >>> --- a/gcc/dse.c >>> +++ b/gcc/dse.c >>> @@ -929,7 +929,9 @@ set_usage_bits (group_info *group, HOST_WIDE_INT >>> offset, HOST_WIDE_INT width, >>> { >>>HOST_WIDE_INT i; >>>bool expr_escapes = can_escape (expr); >>> - if (offset > -MAX_OFFSET && offset + width < MAX_OFFSET) >>> + if (offset > -MAX_OFFSET >>> + && offset < MAX_OFFSET >>> + && offset + width < MAX_OFFSET) >> >> This can still overflow if width is close to HOST_WIDE_INT_MAX. >> Anyway, I don't remember this code too much, but wonder if either offset or >> width or their sum is outside of the -MAX_OFFSET, MAX_OFFSET range if we >> still don't want to record usage bits at least in the intersection of >> -MAX_OFFSET, MAX_OFFSET and offset, offset + width (the latter performed >> with infinite precision; though, if record_store is changed as suggested >> below, offset + width shouldn't overflow). >> >>> for (i=offset; i>>{ >>> bitmap store1; >>> @@ -1536,7 +1538,11 @@ record_store (rtx body, bb_info_t bb_info) >>> } >>>store_info->group_id = group_id; >>>store_info->begin = offset; >>> - store_info->end = offset + width; >>> + if (offset > HOST_WIDE_INT_MAX - width) >>> +store_info->end = HOST_WIDE_INT_MAX; >>> + else >>> +store_info->end = offset + width; >> >> If offset + width overflows, I think we risk wrong-code by doing this, plus >> there are 3 other offset + width computations earlier in record_store >> before we reach this. I think instead we should treat such cases as wild >> stores early, i.e.: >>if (!canon_address (mem, &group_id, &offset, &base)) >> { >>clear_rhs_from_active_local_stores (); >>return 0; >> } >> >>if (GET_MODE (mem) == BLKmode) >> width = MEM_SIZE (mem); >>else >> width = GET_MODE_SIZE (GET_MODE (mem)); >> >> + if (offset > HOST_WIDE_INT_MAX - width) >> +{ >> + clear_rhs_from_active_local_stores (); >> + return 0; >> +} >> >> or so. >> >>> + >>>store_info->is_set = GET_CODE (body) == SET; >>>store_info->rhs = rhs; >>>store_info->const_rhs = const_rhs; >>> @@ -1976,6 +1982,14 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) >>>return; >>> } >>> >>> + if (offset > MAX_OFFSET) >>> +{ >>> + if (dump_file && (dump_flags & TDF_DETAILS)) >>> + fprintf (dump_file, " reaches MAX_OFFSET.\n"); >>> + add_wild_read (bb_info); >>> + return; >>> +} >>> + > > Hi. > > The later one works for me. I'm going to regtest that. > > Ready after it survives regression tests? > > Thanks, > Martin > >> >> Is offset > MAX_OFFSET really problematic (and not just the width != -1 && >> offset + width overflowing case)? >> >>>if (GET_MODE (mem) == BLKmode) >>> width = -1; >>>else >>> >> >> >> Jakub >> >
Re: [PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044).
On 09/20/2017 10:15 AM, Jakub Jelinek wrote: > On Wed, Sep 20, 2017 at 09:50:32AM +0200, Martin Liška wrote: >> Hello. >> >> Following patch handles UBSAN (overflow) in dce.c. > > dse.c ;) > >> --- a/gcc/dse.c >> +++ b/gcc/dse.c >> @@ -929,7 +929,9 @@ set_usage_bits (group_info *group, HOST_WIDE_INT offset, >> HOST_WIDE_INT width, >> { >>HOST_WIDE_INT i; >>bool expr_escapes = can_escape (expr); >> - if (offset > -MAX_OFFSET && offset + width < MAX_OFFSET) >> + if (offset > -MAX_OFFSET >> + && offset < MAX_OFFSET >> + && offset + width < MAX_OFFSET) > > This can still overflow if width is close to HOST_WIDE_INT_MAX. > Anyway, I don't remember this code too much, but wonder if either offset or > width or their sum is outside of the -MAX_OFFSET, MAX_OFFSET range if we > still don't want to record usage bits at least in the intersection of > -MAX_OFFSET, MAX_OFFSET and offset, offset + width (the latter performed > with infinite precision; though, if record_store is changed as suggested > below, offset + width shouldn't overflow). > >> for (i=offset; i>{ >> bitmap store1; >> @@ -1536,7 +1538,11 @@ record_store (rtx body, bb_info_t bb_info) >> } >>store_info->group_id = group_id; >>store_info->begin = offset; >> - store_info->end = offset + width; >> + if (offset > HOST_WIDE_INT_MAX - width) >> +store_info->end = HOST_WIDE_INT_MAX; >> + else >> +store_info->end = offset + width; > > If offset + width overflows, I think we risk wrong-code by doing this, plus > there are 3 other offset + width computations earlier in record_store > before we reach this. I think instead we should treat such cases as wild > stores early, i.e.: >if (!canon_address (mem, &group_id, &offset, &base)) > { >clear_rhs_from_active_local_stores (); >return 0; > } > >if (GET_MODE (mem) == BLKmode) > width = MEM_SIZE (mem); >else > width = GET_MODE_SIZE (GET_MODE (mem)); > > + if (offset > HOST_WIDE_INT_MAX - width) > +{ > + clear_rhs_from_active_local_stores (); > + return 0; > +} > > or so. > >> + >>store_info->is_set = GET_CODE (body) == SET; >>store_info->rhs = rhs; >>store_info->const_rhs = const_rhs; >> @@ -1976,6 +1982,14 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) >>return; >> } >> >> + if (offset > MAX_OFFSET) >> +{ >> + if (dump_file && (dump_flags & TDF_DETAILS)) >> +fprintf (dump_file, " reaches MAX_OFFSET.\n"); >> + add_wild_read (bb_info); >> + return; >> +} >> + Hi. The later one works for me. I'm going to regtest that. Ready after it survives regression tests? Thanks, Martin > > Is offset > MAX_OFFSET really problematic (and not just the width != -1 && > offset + width overflowing case)? > >>if (GET_MODE (mem) == BLKmode) >> width = -1; >>else >> > > > Jakub >
Re: [PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044).
On Wed, Sep 20, 2017 at 09:50:32AM +0200, Martin Liška wrote: > Hello. > > Following patch handles UBSAN (overflow) in dce.c. dse.c ;) > --- a/gcc/dse.c > +++ b/gcc/dse.c > @@ -929,7 +929,9 @@ set_usage_bits (group_info *group, HOST_WIDE_INT offset, > HOST_WIDE_INT width, > { >HOST_WIDE_INT i; >bool expr_escapes = can_escape (expr); > - if (offset > -MAX_OFFSET && offset + width < MAX_OFFSET) > + if (offset > -MAX_OFFSET > + && offset < MAX_OFFSET > + && offset + width < MAX_OFFSET) This can still overflow if width is close to HOST_WIDE_INT_MAX. Anyway, I don't remember this code too much, but wonder if either offset or width or their sum is outside of the -MAX_OFFSET, MAX_OFFSET range if we still don't want to record usage bits at least in the intersection of -MAX_OFFSET, MAX_OFFSET and offset, offset + width (the latter performed with infinite precision; though, if record_store is changed as suggested below, offset + width shouldn't overflow). > for (i=offset; i{ > bitmap store1; > @@ -1536,7 +1538,11 @@ record_store (rtx body, bb_info_t bb_info) > } >store_info->group_id = group_id; >store_info->begin = offset; > - store_info->end = offset + width; > + if (offset > HOST_WIDE_INT_MAX - width) > +store_info->end = HOST_WIDE_INT_MAX; > + else > +store_info->end = offset + width; If offset + width overflows, I think we risk wrong-code by doing this, plus there are 3 other offset + width computations earlier in record_store before we reach this. I think instead we should treat such cases as wild stores early, i.e.: if (!canon_address (mem, &group_id, &offset, &base)) { clear_rhs_from_active_local_stores (); return 0; } if (GET_MODE (mem) == BLKmode) width = MEM_SIZE (mem); else width = GET_MODE_SIZE (GET_MODE (mem)); + if (offset > HOST_WIDE_INT_MAX - width) +{ + clear_rhs_from_active_local_stores (); + return 0; +} or so. > + >store_info->is_set = GET_CODE (body) == SET; >store_info->rhs = rhs; >store_info->const_rhs = const_rhs; > @@ -1976,6 +1982,14 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) >return; > } > > + if (offset > MAX_OFFSET) > +{ > + if (dump_file && (dump_flags & TDF_DETAILS)) > + fprintf (dump_file, " reaches MAX_OFFSET.\n"); > + add_wild_read (bb_info); > + return; > +} > + Is offset > MAX_OFFSET really problematic (and not just the width != -1 && offset + width overflowing case)? >if (GET_MODE (mem) == BLKmode) > width = -1; >else > Jakub
[PATCH] Fix UBSAN errors in dse.c (PR rtl-optimization/82044).
Hello. Following patch handles UBSAN (overflow) in dce.c. Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. Ready to be installed? Martin gcc/ChangeLog: 2017-09-11 Martin Liska PR rtl-optimization/82044 PR tree-optimization/82042 * dse.c (set_usage_bits): Check properly for a big offset value. (record_store): Do not overflow and set maximum value. (check_mem_read_rtx): Bail out for a big offset. --- gcc/dse.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gcc/dse.c b/gcc/dse.c index cff3ac47356..d519ac70ed5 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -929,7 +929,9 @@ set_usage_bits (group_info *group, HOST_WIDE_INT offset, HOST_WIDE_INT width, { HOST_WIDE_INT i; bool expr_escapes = can_escape (expr); - if (offset > -MAX_OFFSET && offset + width < MAX_OFFSET) + if (offset > -MAX_OFFSET + && offset < MAX_OFFSET + && offset + width < MAX_OFFSET) for (i=offset; igroup_id = group_id; store_info->begin = offset; - store_info->end = offset + width; + if (offset > HOST_WIDE_INT_MAX - width) +store_info->end = HOST_WIDE_INT_MAX; + else +store_info->end = offset + width; + store_info->is_set = GET_CODE (body) == SET; store_info->rhs = rhs; store_info->const_rhs = const_rhs; @@ -1976,6 +1982,14 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) return; } + if (offset > MAX_OFFSET) +{ + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " reaches MAX_OFFSET.\n"); + add_wild_read (bb_info); + return; +} + if (GET_MODE (mem) == BLKmode) width = -1; else