On a small number of ports, we only have 2 defined register classes. NO_REGS and ALL_REGS. Examples would include nvptx and vax.

So let's look at check_and_process_move from lra-constraints.c:

  sclass = dclass = NO_REGS;
  if (REG_P (dreg))
    dclass = get_reg_class (REGNO (dreg));
  if (dclass == ALL_REGS)
    /* ALL_REGS is used for new pseudos created by transformations
       like reload of SUBREG_REG (see function
       simplify_operand_subreg).  We don't know their class yet.  We
       should figure out the class from processing the insn
       constraints not in this fast path function.  Even if ALL_REGS
       were a right class for the pseudo, secondary_... hooks usually
       are not define for ALL_REGS.  */
    return false;
  [ ... ]
  /* Set up hard register for a reload pseudo for hook
     secondary_reload because some targets just ignore unassigned
     pseudos in the hook.  */
  if (dclass != NO_REGS && lra_get_regno_hard_regno (REGNO (dreg)) < 0)
    {
      dregno = REGNO (dreg);
      reg_renumber[dregno] = ira_class_hard_regs[dclass][0];
    }


The reference to ira_class_hard_regs is flagged by VRP as having an out-of-bounds array reference. WTF!? Of course it's pretty obvious once you look at the dumps...

On most targets dclass in this code will have a VR_VARYING range and as a result no warning will be issued. But on the ptx and vax ports VRP is able to give us the range ~[NO_REGS,ALL_REGS] aka ~[0,1] The out-of-range array index is now obvious.

The fix is trivial, we just assert that dclass is < LIM_REG_CLASSES, similarly for sclass as it triggers a similar warning.

Bootstrapped and regression tested on x86_64-linux-gnu. Also verified that the ptx and vax ports will build via config-list.mk.

Ok for the trunk?

Jeff


        * lra-constraints.c (check_and_process_move): Constrain the
        range of DCLASS and SCLASS to avoid false positive out of bounds
        array index warning.

diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index b592168..f14c86c 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1127,6 +1127,7 @@ check_and_process_move (bool *change_p, bool *sec_mem_p 
ATTRIBUTE_UNUSED)
   sclass = dclass = NO_REGS;
   if (REG_P (dreg))
     dclass = get_reg_class (REGNO (dreg));
+  gcc_assert (dclass < LIM_REG_CLASSES);
   if (dclass == ALL_REGS)
     /* ALL_REGS is used for new pseudos created by transformations
        like reload of SUBREG_REG (see function
@@ -1138,6 +1139,7 @@ check_and_process_move (bool *change_p, bool *sec_mem_p 
ATTRIBUTE_UNUSED)
     return false;
   if (REG_P (sreg))
     sclass = get_reg_class (REGNO (sreg));
+  gcc_assert (sclass < LIM_REG_CLASSES);
   if (sclass == ALL_REGS)
     /* See comments above.  */
     return false;

Reply via email to