Hi, on s390 (31 bit code with -mesa) the literal pool does not work when using -falign-labels=
We rely on the literal pool base label being exact after the instruction setting up the literal pool base pointer. Using -falign-labels an ".align" command is emitted between the instruction and the label which breaks all literal pool references. The solution is similiar to what the sh target does. The attached patch defines the LABEL_ALIGN target macro and checks if right before label there is a literal pool base insn. If this is the case alignment is suppressed. Bootstrapped on s390. No regression. This fixes the following testcase: < FAIL: gcc.dg/falign-labels-1.c execution test Committed to mainline Bye, -Andreas- 2011-03-09 Andreas Krebbel <andreas.kreb...@de.ibm.com> * config/s390/s390-protos.h (s390_label_align): New prototype. * config/s390/s390.c (s390_label_align): New function. * config/s390/s390.h (LABEL_ALIGN): New target macro definition. Index: gcc/config/s390/s390-protos.h =================================================================== *** gcc/config/s390/s390-protos.h.orig --- gcc/config/s390/s390-protos.h *************** extern void s390_split_access_reg (rtx, *** 101,106 **** --- 101,107 ---- extern void print_operand_address (FILE *, rtx); extern void print_operand (FILE *, rtx, int); extern void s390_output_pool_entry (rtx, enum machine_mode, unsigned int); + extern int s390_label_align (rtx); extern int s390_agen_dep_p (rtx, rtx); extern rtx s390_load_got (void); extern rtx s390_get_thread_pointer (void); Index: gcc/config/s390/s390.c =================================================================== *** gcc/config/s390/s390.c.orig --- gcc/config/s390/s390.c *************** struct GTY(()) machine_function *** 384,389 **** --- 384,415 ---- bytes on a z10 (or higher) CPU. */ #define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048) + /* Return the alignment for LABEL. We default to the -falign-labels + value except for the literal pool base label. */ + int + s390_label_align (rtx label) + { + rtx prev_insn = prev_active_insn (label); + + if (prev_insn == NULL_RTX) + goto old; + + prev_insn = single_set (prev_insn); + + if (prev_insn == NULL_RTX) + goto old; + + prev_insn = SET_SRC (prev_insn); + + /* Don't align literal pool base labels. */ + if (GET_CODE (prev_insn) == UNSPEC + && XINT (prev_insn, 1) == UNSPEC_MAIN_BASE) + return 0; + + old: + return align_labels_log; + } + static enum machine_mode s390_libgcc_cmp_return_mode (void) { Index: gcc/config/s390/s390.h =================================================================== *** gcc/config/s390/s390.h.orig --- gcc/config/s390/s390.h *************** do { \ *** 870,875 **** --- 870,878 ---- /* The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */ #define LOCAL_LABEL_PREFIX "." + #define LABEL_ALIGN(LABEL) \ + s390_label_align (LABEL) + /* How to refer to registers in assembler output. This sequence is indexed by compiler's hard-register-number (see above). */ #define REGISTER_NAMES \