This is the mail archive of the gcc@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]

IA64 compilation failure


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


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