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