This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug rtl-optimization/69771] [6 Regression] ICE on x86_64-linux-gnu at -O0 (in extract_insn, at recog.c:2287)


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69771

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|wrong-code                  |

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Hmm, I think that's ok.

 ~b

is always true, it is ~(int)b != 0 but b is unsigned short and thus
zero-extended
which means the upper bits are always 1.  Thus ~(a || ~b) is 0xfffffffe.  Now
since some C FE change the shift count is interpreted as unsigned char and thus
we end up with d >> 0xfe which is indeed zero.

On the GCC 5 branch we have an int shift count and thus end up with -2 and
a different result (target dependent).

So it's really the ICE we're after, no wrong-code.

And it's a bogus integer constant (not canonicalized) that triggers the issue.

(insn 7 6 8 2 (set (reg:QI 90)
        (const_int 254 [0xfe])) t.i:5 -1
     (nil))

a QImode 0xfe should be sign-extended.

It's expand_binop_directly doing

  mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
  if (xmode1 != VOIDmode && xmode1 != mode1)
    {
      xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
      mode1 = xmode1;
    }

with VOIDmode xop1, expanded from a int typed constant and thus canonicalized
to SImode.  We fail to canonicalize the constant here if xmode1 (QImode)
and mode (QImode) match.

Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c        (revision 233369)
+++ gcc/optabs.c        (working copy)
@@ -1020,8 +1020,8 @@ expand_binop_directly (machine_mode mode
       mode0 = xmode0;
     }

-  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;

fixes this by always converting VOIDmode inputs.  The comment even says so:

  /* In case the insn wants input operands in modes different from
     those of the actual operands, convert the operands.  It would
     seem that we don't need to convert CONST_INTs, but we do, so
     that they're properly zero-extended, sign-extended or truncated
     for their mode.  */

but for some reason the code doesn't agree with it.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]