This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
IA64 compilation failure
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: gcc at gcc dot gnu dot org
- Date: Wed, 18 Feb 2004 17:02:50 -0800 (PST)
- Subject: IA64 compilation failure
- Reply-to: sje at cup dot hp dot com
I am trying to figure out why the attached program will not compile on
IA64 Linux with -O2 but I am not sure what is going on. I was hoping
someone might have some ideas to help me. The problem appears to be
related to if-conversion, if I turn that off then it will compile.
With -O2 and if-conversion the compile dies with:
x.c:20: error: unrecognizable insn:
(insn 50 49 32 0 (set (zero_extract:DI (reg/v:DI 341 [ yyval ])
(const_int 32 [0x20])
(const_int 0 [0x0]))
(reg:DI 354)) -1 (insn_list 51 (insn_list 49 (nil)))
(expr_list:REG_DEAD (reg:DI 354)
(nil)))
x.c:20: internal compiler error: in extract_insn, at recog.c:2083
If I look at x.c.14.ce1 with if-conversion turned off I see:
| (insn 23 42 24 1 (parallel [
| (set (zero_extract:DI (reg/v:DI 341 [ yyval ])
| (const_int 32 [0x20])
| (const_int 0 [0x0]))
| (subreg:DI (reg:SI 345 [ <variable>.intval ]) 0))
| (clobber (reg:DI 351))
| ]) 56 {shift_mix4left} (nil)
| (nil))
But if I look at x.c.14.ce1 with if-conversion on I see:
| (insn 49 17 50 0 (set (reg:DI 354)
| (if_then_else:DI (ne (reg:BI 347)
| (const_int 0 [0x0]))
| (subreg:DI (reg:SI 346 [ <variable>.intval ]) 0)
| (subreg:DI (reg:SI 345 [ <variable>.intval ]) 0))) 226 {*cmovdi_internal} (nil)
| (nil))
|
| (insn 50 49 32 0 (set (zero_extract:DI (reg/v:DI 341 [ yyval ])
| (const_int 32 [0x20])
| (const_int 0 [0x0]))
| (reg:DI 354)) -1 (nil)
| (nil))
There is no clobber on this zero_extract and I wonder if that is the
problem, that I need a register that I can clobber in order to expand
the zero_extract.
I noticed one odd thing in ia64.md that I couldn't understand and may or
may not be related. In ia64.md after the definition of shift_mix4left,
there are two define_split's. They are identical except that one has a
condition "reload_completed" and the other a condition "! reload_completed".
Why not just have one version with no condition, or is one of these in
error? I tried removing the "! reload_completed" version since there
don't seem to be any other define_split's like this but it didn't help.
Here is the test case:
typedef union YYSTYPE {
double dval;
int intval;
} YYSTYPE;
YYSTYPE *x;
int
knparse (void)
{
YYSTYPE yyvsa[200];
register YYSTYPE *yyvsp;
YYSTYPE yyval, *x;
yyvsp = &yyvsa[100];
if (yyvsp[3].intval > yyvsp[0].intval)
yyval.intval = yyvsp[3].intval;
else
yyval.intval = yyvsp[0].intval;
*x = yyval;
}