This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/69771] [6 Regression] ICE on x86_64-linux-gnu at -O0 (in extract_insn, at recog.c:2287)
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 12 Feb 2016 09:38:09 +0000
- Subject: [Bug rtl-optimization/69771] [6 Regression] ICE on x86_64-linux-gnu at -O0 (in extract_insn, at recog.c:2287)
- Auto-submitted: auto-generated
- References: <bug-69771-4 at http dot gcc dot gnu dot org/bugzilla/>
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.