On 11/18/2015 07:15 AM, Nick Clifton wrote:
Hi Guys,

   I recently discovered a bug in the current Redundant Extension
   Elimination optimization.  If the candidate extension instruction
   increases the number of hard registers used, the pass does not check
   to see if these extra registers are live between the definition and
   the extension.

   For example:

     (insn  44 (set (reg:QI r11) (mem:QI (reg:HI r20)))
     (insn  45 (set (reg:QI r10) (mem:QI (reg:HI r18)))
     [...]
     (insn  71 (set (reg:HI r14) (zero_extend:HI (reg:QI r11)))
     [...]
     (insn  88 (set (reg:HI r10) (zero_extend:HI (reg:QI r10)))

   (This is on the RL78 target where HImode values occupy two hard
   registers and QImode values only one.  The bug however is generic, not
   RL78 specific).
Right. I can recall walking though multi-reg cases on my whiteboard. There was one particular case Jakub was concerned about in this space, but I couldn't contrive a testcase to trigger and I was getting to the point where I was struggling to be able to reason about the behaviour of the code.





   The REE pass transforms this into:

     (insn  44 (set (reg:QI r11) (mem:QI (reg:HI r20)))
     (insn  45 (set (reg:HI r10) (zero_extend:HI (mem:QI (reg:HI r18))))
     [...]
     (insn  71 (set (reg:HI r14) (zero_extend:HI (reg:QI r11)))
     [...]
     (insn  88 deleted)

   Note how the new set at insn 45 clobbers the value loaded by insn 44
   into r11.
Right.


   The patch below is my attempt to fix this.  It is not correct
   however.  I could not work out how to determine if a given hard
   register is live at any point between two insns.  So instead I used
   the liveness information associated with the basic block containing
   the definition.  If one of the extended registers is live or becomes
   live in this block, and this block is not the same block as the one
   containing the extension insn, then I stop the optimization.  This
   works for the RL78 for all of the cases that I could find.
The way this pass has dealt with this class of problems is the various routines in rtlanal.c reg_used_between_p, reg_set_between_p and the like.



   So ... comments please ?

   Will gcc ever generate a single basic block that contains both the
   definition and the extension instructions, but also where the extra
   hard registers are used for another purpose as well ?
I can't see any reason why it would not.


jeff

Reply via email to