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]

pr5649 on powerpc (broken splitters)


Hi,

look at the bug-report 5649.  current HEAD fail on this program with -O2
on powerpc-elf:

int foo(void);
void bar(int x) {
    if (foo()) {
        if (x==0) return;
        if (foo()) { if (foo()) x++; if (x>0) foo(); }
    }
}

It produces an unrecognizable insns.  I know what happens, but am not
sure, how to fix it, esp. because the code in question is already in CVS
since some time.  For the following refer to rs6000.md around line 11003
(unfortunately all are unnamed patterns).  OK, what happens, is that
somewhen an insn (uid 39) matching that:

(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
 (compare:CC (plus:SI (lshiftrt:SI (neg:SI (abs:SI
     (match_operand:SI 1 "gpc_reg_operand" "r,r")))
                       (const_int 31))
              (match_operand:SI 2 "gpc_reg_operand" "r,r"))
  (const_int 0)))
 (clobber (match_scratch:SI 3 "=&r,&r"))

is created, with Op0 being cr7 (i.e. != cr0).  Therefore alternative 2 is
chosen, which means that pattern shall be splitted.  The applying splitter
is right below the above define_insn, matching the same structure, with
the difference, that s/cc_reg_operand/cc_reg_not_cr0_operand/.  It only is
active when reload_completed.  It splits the above insn into two insns,
namely:

(set (match_dup 3)
     (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1)))
               (const_int 31))
      (match_dup 2)))
(set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))

Note esp. that here of course no clobbers are emitted (we are after
reload).  Now we have a problem.  Because the first of the above two insns
isn't recognizable anymore (it actually fails right after splitting,
because cleanup_subreg_operands() is run afterwards, which calls
extract_insn(), but that's not important, deactivating that makes it
simply fail a little later in final.c).

If you look carefully there actually _is_ a pattern nearly matching the
above insns (two patterns above the initial define_insn from above),
except that it needs a further (clobber match_scratch) (it btw. really
needs it, because it's used in the string template).  If you search
further there are no other patterns which could match this (with or
without clobbers).

OK, so we have the situation, that after reload is completed some
splitters emit insns, which need further scratches to be recognized, which
seems broken to me.  Nobody is going to fill them in, after all.  (So it
wouldn't help, if we simply would recognize the insns with possible
clobber adding).

I can't see how this possibly can work, but as I said, the code in
question is already since quite some time in CVS, so I ask for
clarification.  For now I simply deleted the "?y" alternative of the
initial define_insn, which makes that insn not be splitted anymore (and in
this case not used at all).  This makes the program compile (unlike some
other tries like deactivating only the splitter, only doing it when before
reload and so on).

Thoughts?


Ciao,
Michael.


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