[PATCH] Fix PR69771, bogus CONST_INT during shift expansion
Jakub Jelinek
jakub@redhat.com
Fri Feb 12 13:28:00 GMT 2016
On Fri, Feb 12, 2016 at 01:50:08PM +0100, Richard Biener wrote:
> > - mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
> > - if (xmode1 != VOIDmode && xmode1 != mode1)
> > + mode1 = GET_MODE (xop1);
> > + if (xmode1 != mode1)
> > {
> > xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
> > mode1 = xmode1;
> >
> > so if xop1 is not VOIDmode and already of xmode1 we won't do anything.
> > But if it is VOIDmode (and xmode1 is not VOIDmode) we'll always
> > do convert_modes.
> >
> > The only thing that can (hopefully not) happen is that xmode1
> > is VOIDmode but mode1 is not (maybe removing the xmode1 != VOIDmode
> > check is a bit too optimistic here). Not sure if there can be
> > valid patterns requesting a VOIDmode op ... (and not only accept
> > CONST_INTs).
>
> Oh, bootstrap & testing went fine on x86_64-unknown-linux-gnu.
>
> If we can agree on the patch then I'll pick up the testcase from
> your patch (and adjust mine).
Another possibility, only do the convert_modes from VOIDmode for
shift_optab_p's xop1, and keep doing what we've done before otherwise.
2016-02-12 Jakub Jelinek <jakub@redhat.com>
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 testcase.
--- gcc/optabs.c.jj 2016-02-12 00:50:30.410240366 +0100
+++ gcc/optabs.c 2016-02-12 10:33:32.743492532 +0100
@@ -988,7 +988,7 @@ expand_binop_directly (machine_mode mode
from_mode, 1);
machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
- machine_mode mode0, mode1, tmp_mode;
+ machine_mode mode0, mode1 = mode, tmp_mode;
struct expand_operand ops[3];
bool commutative_p;
rtx_insn *pat;
@@ -1006,6 +1006,8 @@ expand_binop_directly (machine_mode mode
xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
if (!shift_optab_p (binoptab))
xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
+ else
+ mode1 = VOIDmode;
/* In case the insn wants input operands in modes different from
those of the actual operands, convert the operands. It would
@@ -1020,7 +1020,7 @@ expand_binop_directly (machine_mode mode
mode0 = xmode0;
}
- mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
+ mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode1;
if (xmode1 != VOIDmode && xmode1 != mode1)
{
xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
--- gcc/testsuite/c-c++-common/pr69764.c.jj 2016-02-12 10:27:34.522587995 +0100
+++ gcc/testsuite/c-c++-common/pr69764.c 2016-02-12 10:27:34.522587995 +0100
@@ -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" } */
+}
--- gcc/testsuite/gcc.dg/torture/pr69771.c.jj 2016-02-12 10:27:34.522587995 +0100
+++ gcc/testsuite/gcc.dg/torture/pr69771.c 2016-02-12 10:27:34.522587995 +0100
@@ -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" } */
+}
Jakub
More information about the Gcc-patches
mailing list