From c3090c1f521bb5fedd5e7f977bce1bf0e1fc0a8e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 12 Feb 2016 17:49:44 +0100 Subject: [PATCH] re PR rtl-optimization/69764 (ICE on x86_64-linux-gnu at -O0 (in decompose, at rtl.h:2107)) PR rtl-optimization/69764 PR rtl-optimization/69771 * optabs.c (expand_binop_directly): For shift_optab_p, force convert_modes with VOIDmode if xop1 has VOIDmode. * c-c++-common/pr69764.c: New test. * gcc.dg/torture/pr69771.c: New test. From-SVN: r233381 --- gcc/ChangeLog | 7 +++++ gcc/optabs.c | 9 +++++- gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/c-c++-common/pr69764.c | 38 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr69771.c | 12 ++++++++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/c-c++-common/pr69764.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr69771.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 65b32b85f56..871a2f076ee 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-02-12 Jakub Jelinek + + PR rtl-optimization/69764 + PR rtl-optimization/69771 + * optabs.c (expand_binop_directly): For shift_optab_p, force + convert_modes with VOIDmode if xop1 has VOIDmode. + 2016-02-12 Ilya Enkovich PR target/69729 diff --git a/gcc/optabs.c b/gcc/optabs.c index e1ba6150473..b651878b725 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -993,6 +993,7 @@ expand_binop_directly (machine_mode mode, optab binoptab, bool commutative_p; rtx_insn *pat; rtx xop0 = op0, xop1 = op1; + bool canonicalize_op1 = false; /* If it is a commutative operator and the modes would match if we would swap the operands, we can save the conversions. */ @@ -1006,6 +1007,11 @@ expand_binop_directly (machine_mode mode, optab binoptab, xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp); if (!shift_optab_p (binoptab)) xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp); + else + /* Shifts and rotates often use a different mode for op1 from op0; + for VOIDmode constants we don't know the mode, so force it + to be canonicalized using convert_modes. */ + canonicalize_op1 = true; /* In case the insn wants input operands in modes different from those of the actual operands, convert the operands. It would @@ -1020,7 +1026,8 @@ expand_binop_directly (machine_mode mode, optab binoptab, mode0 = xmode0; } - mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode; + mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1) + ? GET_MODE (xop1) : mode); if (xmode1 != VOIDmode && xmode1 != mode1) { xop1 = convert_modes (xmode1, mode1, xop1, unsignedp); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffb14ef3d58..dfae7fc6321 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-02-12 Jakub Jelinek + + PR rtl-optimization/69764 + PR rtl-optimization/69771 + * c-c++-common/pr69764.c: New test. + * gcc.dg/torture/pr69771.c: New test. + 2016-02-12 Marek Polacek * g++.dg/torture/init-list1.C: New. diff --git a/gcc/testsuite/c-c++-common/pr69764.c b/gcc/testsuite/c-c++-common/pr69764.c new file mode 100644 index 00000000000..79623ec7373 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr69764.c @@ -0,0 +1,38 @@ +/* PR rtl-optimization/69764 */ +/* { dg-do compile { target int32plus } } */ + +unsigned char +fn1 (unsigned char a) +{ + return a >> ~6; /* { dg-warning "right shift count is negative" } */ +} + +unsigned short +fn2 (unsigned short a) +{ + return a >> ~6; /* { dg-warning "right shift count is negative" } */ +} + +unsigned int +fn3 (unsigned int a) +{ + return a >> ~6; /* { dg-warning "right shift count is negative" } */ +} + +unsigned char +fn4 (unsigned char a) +{ + return a >> 0xff03; /* { dg-warning "right shift count >= width of type" } */ +} + +unsigned short +fn5 (unsigned short a) +{ + return a >> 0xff03; /* { dg-warning "right shift count >= width of type" } */ +} + +unsigned int +fn6 (unsigned int a) +{ + return a >> 0xff03; /* { dg-warning "right shift count >= width of type" } */ +} diff --git a/gcc/testsuite/gcc.dg/torture/pr69771.c b/gcc/testsuite/gcc.dg/torture/pr69771.c new file mode 100644 index 00000000000..8314c82c764 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr69771.c @@ -0,0 +1,12 @@ +/* PR rtl-optimization/69771 */ +/* { dg-do compile } */ + +unsigned char a = 5, c; +unsigned short b = 0; +unsigned d = 0x76543210; + +void +foo (void) +{ + c = d >> ~(a || ~b); /* { dg-warning "shift count is negative" } */ +}