Hi,

reloads of symbolic addresses are done using larl (if possible) which
allows to load a symbol_ref or label_ref plus an even addend.  Since
these addresses are constants special care has to be taken in
preferred_reload class.  We have to return NO_REGS in case of a
malformed address like symref + odd addend.  Otherwise reload assumes
that these can be directly reloaded into a register.

Fixed with the attached patch.

Bootstrapped an regtested on s390, s390x with mainline and 4.6.

Committed to mainline.
Ok for 4.6?

Bye,

-Andreas-


2011-03-24  Andreas Krebbel  <andreas.kreb...@de.ibm.com>

        * config/s390/s390.c (s390_preferred_reload_class): Return NO_REGS
        for invalid symbolic addresses.
        (s390_secondary_reload): Don't use s390_check_symref_alignment for
        larl operands.


Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig
--- gcc/config/s390/s390.c
*************** s390_preferred_reload_class (rtx op, reg
*** 3003,3014 ****
         it is most likely being used as an address, so
         prefer ADDR_REGS.  If 'class' is not a superset
         of ADDR_REGS, e.g. FP_REGS, reject this reload.  */
-       case PLUS:
        case LABEL_REF:
        case SYMBOL_REF:
        case CONST:
        if (reg_class_subset_p (ADDR_REGS, rclass))
!           return ADDR_REGS;
        else
          return NO_REGS;
  
--- 3003,3018 ----
         it is most likely being used as an address, so
         prefer ADDR_REGS.  If 'class' is not a superset
         of ADDR_REGS, e.g. FP_REGS, reject this reload.  */
        case LABEL_REF:
        case SYMBOL_REF:
        case CONST:
+       if (!legitimate_reload_constant_p (op))
+           return NO_REGS;
+       /* fallthrough */
+       case PLUS:
+       /* load address will be used.  */
        if (reg_class_subset_p (ADDR_REGS, rclass))
!         return ADDR_REGS;
        else
          return NO_REGS;
  
*************** s390_secondary_reload (bool in_p, rtx x,
*** 3126,3137 ****
  
    if (TARGET_Z10)
      {
        /* On z10 several optimizer steps may generate larl operands with
         an odd addend.  */
        if (in_p
!         && s390_symref_operand_p (x, NULL, NULL)
          && mode == Pmode
!         && !s390_check_symref_alignment (x, 2))
        sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10
                      : CODE_FOR_reloadsi_larl_odd_addend_z10);
  
--- 3130,3145 ----
  
    if (TARGET_Z10)
      {
+       HOST_WIDE_INT offset;
+       rtx symref;
+ 
        /* On z10 several optimizer steps may generate larl operands with
         an odd addend.  */
        if (in_p
!         && s390_symref_operand_p (x, &symref, &offset)
          && mode == Pmode
!         && !SYMBOL_REF_ALIGN1_P (symref)
!         && (offset & 1) == 1)
        sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10
                      : CODE_FOR_reloadsi_larl_odd_addend_z10);
  

Reply via email to