diff mbox

Fix PR78588 - rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too large for 64-bit type

Message ID 20161129140815.GA441@x4
State New
Headers show

Commit Message

Markus Trippelsdorf Nov. 29, 2016, 2:08 p.m. UTC
Building gcc with -fsanitize=undefined shows:
 rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too
 large for 64-bit type 'long unsigned int'

5210   return nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))
5211          ? 1 : bitwidth - floor_log2 (nonzero) - 1;

Here (bitwidth - 1) wraps around because bitwidth is zero and unsigned. 

Fix by returning earlier if bitwidth is zero.

Tested on ppc64le.
OK for trunk?

Thanks.

  * rtlanal.c (num_sign_bit_copies1): Check for zero bitwidth.


--
Markus

Comments

Jakub Jelinek Nov. 29, 2016, 2:14 p.m. UTC | #1
On Tue, Nov 29, 2016 at 03:08:15PM +0100, Markus Trippelsdorf wrote:
> Building gcc with -fsanitize=undefined shows:
>  rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too
>  large for 64-bit type 'long unsigned int'
> 
> 5210   return nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))
> 5211          ? 1 : bitwidth - floor_log2 (nonzero) - 1;
> 
> Here (bitwidth - 1) wraps around because bitwidth is zero and unsigned. 

Which modes have precision of 0?  I'd expect just VOIDmode and BLKmode, any
others?  And for those I'd say it is a bug to call num_sign_bit_copies*.

> Tested on ppc64le.
> OK for trunk?
> 
> Thanks.
> 
>   * rtlanal.c (num_sign_bit_copies1): Check for zero bitwidth.
> 
> diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
> index 4e4eb2ef3458..918088a0db8e 100644
> --- a/gcc/rtlanal.c
> +++ b/gcc/rtlanal.c
> @@ -5203,7 +5203,7 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x,
>       safely compute the mask for this mode, always return BITWIDTH.  */
> 
>    bitwidth = GET_MODE_PRECISION (mode);
> -  if (bitwidth > HOST_BITS_PER_WIDE_INT)
> +  if (bitwidth == 0 || bitwidth > HOST_BITS_PER_WIDE_INT)
>      return 1;
> 
>    nonzero = nonzero_bits (x, mode);
> 
> --
> Markus

	Jakub
Markus Trippelsdorf Nov. 29, 2016, 2:21 p.m. UTC | #2
On 2016.11.29 at 15:14 +0100, Jakub Jelinek wrote:
> On Tue, Nov 29, 2016 at 03:08:15PM +0100, Markus Trippelsdorf wrote:
> > Building gcc with -fsanitize=undefined shows:
> >  rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too
> >  large for 64-bit type 'long unsigned int'
> >
> > 5210   return nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))
> > 5211          ? 1 : bitwidth - floor_log2 (nonzero) - 1;
> >
> > Here (bitwidth - 1) wraps around because bitwidth is zero and unsigned.
>
> Which modes have precision of 0?  I'd expect just VOIDmode and BLKmode, any
> others?  And for those I'd say it is a bug to call num_sign_bit_copies*.

Yes, only VOIDmode and BLKmode:

 233 const unsigned short mode_precision[NUM_MACHINE_MODES] =
 234 {
 235   0,                       /* VOID */
 236   0,                       /* BLK */


--
Markus
Markus Trippelsdorf Nov. 29, 2016, 3:01 p.m. UTC | #3
On 2016.11.29 at 15:21 +0100, Markus Trippelsdorf wrote:
> On 2016.11.29 at 15:14 +0100, Jakub Jelinek wrote:
> > On Tue, Nov 29, 2016 at 03:08:15PM +0100, Markus Trippelsdorf wrote:
> > > Building gcc with -fsanitize=undefined shows:
> > >  rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too
> > >  large for 64-bit type 'long unsigned int'
> > >
> > > 5210   return nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))
> > > 5211          ? 1 : bitwidth - floor_log2 (nonzero) - 1;
> > >
> > > Here (bitwidth - 1) wraps around because bitwidth is zero and unsigned.
> >
> > Which modes have precision of 0?  I'd expect just VOIDmode and BLKmode, any
> > others?  And for those I'd say it is a bug to call num_sign_bit_copies*.
> 
> Yes, only VOIDmode and BLKmode:
> 
>  233 const unsigned short mode_precision[NUM_MACHINE_MODES] =
>  234 {
>  235   0,                       /* VOID */
>  236   0,                       /* BLK */

markus@x4 libsupc++ % cat cp-demangle.i
d_demangle_callback_mangled() {
  if (strncmp(d_demangle_callback_mangled, "", 1))
    d_type();
}

markus@x4 libsupc++ % UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 /var/tmp/gcc_build_dir_/./gcc/cc1 -w -fpreprocessed cp-demangle.i -quiet -dumpbase cp-demangle.i -mtune=generic -march=x86-64 -auxbase cp-demangle -O2 -version -o /dev/null
GNU C11 (GCC) version 7.0.0 20161129 (experimental) (x86_64-pc-linux-gnu)
        compiled by GNU C version 7.0.0 20161129 (experimental), GMP version 6.1.1, MPFR version 3.1.5, MPC version 1.0.3, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
GNU C11 (GCC) version 7.0.0 20161129 (experimental) (x86_64-pc-linux-gnu)
        compiled by GNU C version 7.0.0 20161129 (experimental), GMP version 6.1.1, MPFR version 3.1.5, MPC version 1.0.3, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 7cca725773f8a0693a2905f8af7b733c
../../gcc/gcc/rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too large for 64-bit type 'long unsigned int'
    #0 0x1b40fe1 in num_sign_bit_copies1 ../../gcc/gcc/rtlanal.c:5210
    #1 0x35ef5f1 in if_then_else_cond ../../gcc/gcc/combine.c:9180
    #2 0x35ef199 in if_then_else_cond ../../gcc/gcc/combine.c:9034
    #3 0x35ef199 in if_then_else_cond ../../gcc/gcc/combine.c:9034
    #4 0x3625f98 in combine_simplify_rtx ../../gcc/gcc/combine.c:5604
    #5 0x3632525 in subst ../../gcc/gcc/combine.c:5487
    #6 0x36327d6 in subst ../../gcc/gcc/combine.c:5425
    #7 0x3632bd7 in subst ../../gcc/gcc/combine.c:5354
    #8 0x3641a74 in try_combine ../../gcc/gcc/combine.c:3347
    #9 0x365727b in combine_instructions ../../gcc/gcc/combine.c:1421
    #10 0x365727b in rest_of_handle_combine ../../gcc/gcc/combine.c:14581
    #11 0x365727b in execute ../../gcc/gcc/combine.c:14626
    #12 0x195ad18 in execute_one_pass(opt_pass*) ../../gcc/gcc/passes.c:2370
    #13 0x195cbab in execute_pass_list_1 ../../gcc/gcc/passes.c:2459
    #14 0x195cbd4 in execute_pass_list_1 ../../gcc/gcc/passes.c:2460
    #15 0x195cc64 in execute_pass_list(function*, opt_pass*) ../../gcc/gcc/passes.c:2470
    #16 0xc75deb in cgraph_node::expand() ../../gcc/gcc/cgraphunit.c:2001
    #17 0xc7b2fa in expand_all_functions ../../gcc/gcc/cgraphunit.c:2137
    #18 0xc7b2fa in symbol_table::compile() ../../gcc/gcc/cgraphunit.c:2494
    #19 0xc854b7 in symbol_table::compile() ../../gcc/gcc/cgraphunit.c:2587
    #20 0xc854b7 in symbol_table::finalize_compilation_unit() ../../gcc/gcc/cgraphunit.c:2584
    #21 0x1d3ea10 in compile_file ../../gcc/gcc/toplev.c:488
    #22 0x629a14 in do_compile ../../gcc/gcc/toplev.c:1983
    #23 0x629a14 in toplev::main(int, char**) ../../gcc/gcc/toplev.c:2117
    #24 0x62c046 in main ../../gcc/gcc/main.c:39
    #25 0x7f4b6600f310 in __libc_start_main ../csu/libc-start.c:286
    #26 0x62c469 in _start (/var/tmp/gcc_build_dir_/gcc/cc1+0x62c469)
Markus Trippelsdorf Nov. 29, 2016, 3:07 p.m. UTC | #4
On 2016.11.29 at 16:01 +0100, Markus Trippelsdorf wrote:
> On 2016.11.29 at 15:21 +0100, Markus Trippelsdorf wrote:
> > On 2016.11.29 at 15:14 +0100, Jakub Jelinek wrote:
> > > On Tue, Nov 29, 2016 at 03:08:15PM +0100, Markus Trippelsdorf wrote:
> > > > Building gcc with -fsanitize=undefined shows:
> > > >  rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too
> > > >  large for 64-bit type 'long unsigned int'
> > > >
> > > > 5210   return nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))
> > > > 5211          ? 1 : bitwidth - floor_log2 (nonzero) - 1;
> > > >
> > > > Here (bitwidth - 1) wraps around because bitwidth is zero and unsigned.
> > >
> > > Which modes have precision of 0?  I'd expect just VOIDmode and BLKmode, any
> > > others?  And for those I'd say it is a bug to call num_sign_bit_copies*.
> > 
> > Yes, only VOIDmode and BLKmode:
> > 
> >  233 const unsigned short mode_precision[NUM_MACHINE_MODES] =
> >  234 {
> >  235   0,                       /* VOID */
> >  236   0,                       /* BLK */
> 
> markus@x4 libsupc++ % cat cp-demangle.i
> d_demangle_callback_mangled() {
>   if (strncmp(d_demangle_callback_mangled, "", 1))
>     d_type();
> }
> 
> markus@x4 libsupc++ % UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 /var/tmp/gcc_build_dir_/./gcc/cc1 -w -fpreprocessed cp-demangle.i -quiet -dumpbase cp-demangle.i -mtune=generic -march=x86-64 -auxbase cp-demangle -O2 -version -o /dev/null
> GNU C11 (GCC) version 7.0.0 20161129 (experimental) (x86_64-pc-linux-gnu)
>         compiled by GNU C version 7.0.0 20161129 (experimental), GMP version 6.1.1, MPFR version 3.1.5, MPC version 1.0.3, isl version none
> GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
> GNU C11 (GCC) version 7.0.0 20161129 (experimental) (x86_64-pc-linux-gnu)
>         compiled by GNU C version 7.0.0 20161129 (experimental), GMP version 6.1.1, MPFR version 3.1.5, MPC version 1.0.3, isl version none
> GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
> Compiler executable checksum: 7cca725773f8a0693a2905f8af7b733c
> ../../gcc/gcc/rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too large for 64-bit type 'long unsigned int'
>     #0 0x1b40fe1 in num_sign_bit_copies1 ../../gcc/gcc/rtlanal.c:5210
>     #1 0x35ef5f1 in if_then_else_cond ../../gcc/gcc/combine.c:9180
>     #2 0x35ef199 in if_then_else_cond ../../gcc/gcc/combine.c:9034
>     #3 0x35ef199 in if_then_else_cond ../../gcc/gcc/combine.c:9034
>     #4 0x3625f98 in combine_simplify_rtx ../../gcc/gcc/combine.c:5604
>     #5 0x3632525 in subst ../../gcc/gcc/combine.c:5487
>     #6 0x36327d6 in subst ../../gcc/gcc/combine.c:5425
>     #7 0x3632bd7 in subst ../../gcc/gcc/combine.c:5354
>     #8 0x3641a74 in try_combine ../../gcc/gcc/combine.c:3347
>     #9 0x365727b in combine_instructions ../../gcc/gcc/combine.c:1421
>     #10 0x365727b in rest_of_handle_combine ../../gcc/gcc/combine.c:14581
>     #11 0x365727b in execute ../../gcc/gcc/combine.c:14626
>     #12 0x195ad18 in execute_one_pass(opt_pass*) ../../gcc/gcc/passes.c:2370
>     #13 0x195cbab in execute_pass_list_1 ../../gcc/gcc/passes.c:2459
>     #14 0x195cbd4 in execute_pass_list_1 ../../gcc/gcc/passes.c:2460
>     #15 0x195cc64 in execute_pass_list(function*, opt_pass*) ../../gcc/gcc/passes.c:2470
>     #16 0xc75deb in cgraph_node::expand() ../../gcc/gcc/cgraphunit.c:2001
>     #17 0xc7b2fa in expand_all_functions ../../gcc/gcc/cgraphunit.c:2137
>     #18 0xc7b2fa in symbol_table::compile() ../../gcc/gcc/cgraphunit.c:2494
>     #19 0xc854b7 in symbol_table::compile() ../../gcc/gcc/cgraphunit.c:2587
>     #20 0xc854b7 in symbol_table::finalize_compilation_unit() ../../gcc/gcc/cgraphunit.c:2584
>     #21 0x1d3ea10 in compile_file ../../gcc/gcc/toplev.c:488
>     #22 0x629a14 in do_compile ../../gcc/gcc/toplev.c:1983
>     #23 0x629a14 in toplev::main(int, char**) ../../gcc/gcc/toplev.c:2117
>     #24 0x62c046 in main ../../gcc/gcc/main.c:39
>     #25 0x7f4b6600f310 in __libc_start_main ../csu/libc-start.c:286
>     #26 0x62c469 in _start (/var/tmp/gcc_build_dir_/gcc/cc1+0x62c469)

(gdb) p mode
$1 = BLKmode

#6  0x00000000035ef5f2 in if_then_else_cond (x=0x7ffff60d3888,
ptrue=ptrue@entry=0x7fffffffd940, pfalse=pfalse@entry=0x7fffffffd950) at ../../gcc/gcc/combine.c:9180
9180                   && num_sign_bit_copies (x, mode) == GET_MODE_PRECISION (mode)))
(gdb) l
9175
9176      /* If X is known to be either 0 or -1, those are the true and
9177         false values when testing X.  */
9178      else if (x == constm1_rtx || x == const0_rtx
9179               || (mode != VOIDmode
9180                   && num_sign_bit_copies (x, mode) == GET_MODE_PRECISION (mode)))
9181        {
9182          *ptrue = constm1_rtx, *pfalse = const0_rtx;
9183          return x;
9184        }
diff mbox

Patch

diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 4e4eb2ef3458..918088a0db8e 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -5203,7 +5203,7 @@  num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x,
      safely compute the mask for this mode, always return BITWIDTH.  */

   bitwidth = GET_MODE_PRECISION (mode);
-  if (bitwidth > HOST_BITS_PER_WIDE_INT)
+  if (bitwidth == 0 || bitwidth > HOST_BITS_PER_WIDE_INT)
     return 1;

   nonzero = nonzero_bits (x, mode);