Improves the code generation by getting rid of redundant LAs, as seen in the following example:
- la %r1,0(%r13) - lg %r4,0(%r1) + lg %r4,0(%r13) Also allows to proceed with the merge of movdi_64 and movdi_larl. Currently LRA decides to spill literal pool references back to the literal pool, because it preliminarily chooses alternatives with CT_MEMORY constraints without calling satisfies_memory_constraint_p (). Later on it notices that the constraint is wrong and fixes it by spilling. The constraint in this case is "b", and the operand is a literal pool reference. There is no reason to reject them. The current behavior was introduced, apparently unintentionally, by https://gcc.gnu.org/ml/gcc-patches/2010-09/msg00812.html The patch affects a little bit more than mentioned in the subject, because it changes s390_loadrelative_operand_p (), which is called not only for checking the "b" constraint. However, the only caller for which it should really not accept literal pool references is s390_check_qrst_address (), so it was changed to explicitly do so. gcc/ChangeLog: 2018-10-18 Ilya Leoshkevich <i...@linux.ibm.com> * config/s390/s390.c (s390_loadrelative_operand_p): Accept literal pool references. (s390_check_qrst_address): Adapt to the new behavior of s390_loadrelative_operand_p (). gcc/testsuite/ChangeLog: 2018-10-18 Ilya Leoshkevich <i...@linux.ibm.com> * gcc.target/s390/litpool-int.c: New test. --- gcc/config/s390/s390.c | 9 +++++---- gcc/testsuite/gcc.target/s390/litpool-int.c | 12 ++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/litpool-int.c diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index ed307c3598b..0b7e44b62e1 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -3110,8 +3110,7 @@ s390_legitimate_address_without_index_p (rtx op) Valid addresses are single references or a sum of a reference and a constant integer. Return these parts in SYMREF and ADDEND. You can pass NULL in REF and/or ADDEND if you are not interested in these - values. Literal pool references are *not* considered symbol - references. */ + values. */ static bool s390_loadrelative_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend) @@ -3130,7 +3129,7 @@ s390_loadrelative_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend) addr = XEXP (addr, 0); } - if ((GET_CODE (addr) == SYMBOL_REF && !CONSTANT_POOL_ADDRESS_P (addr)) + if (GET_CODE (addr) == SYMBOL_REF || (GET_CODE (addr) == UNSPEC && (XINT (addr, 1) == UNSPEC_GOTENT || XINT (addr, 1) == UNSPEC_PLT))) @@ -3153,6 +3152,7 @@ s390_loadrelative_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend) static int s390_check_qrst_address (char c, rtx op, bool lit_pool_ok) { + rtx symref; struct s390_address addr; bool decomposed = false; @@ -3161,7 +3161,8 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok) /* This check makes sure that no symbolic address (except literal pool references) are accepted by the R or T constraints. */ - if (s390_loadrelative_operand_p (op, NULL, NULL)) + if (s390_loadrelative_operand_p (op, &symref, NULL) + && (!lit_pool_ok || !CONSTANT_POOL_ADDRESS_P (symref))) return 0; /* Ensure literal pool references are only accepted if LIT_POOL_OK. */ diff --git a/gcc/testsuite/gcc.target/s390/litpool-int.c b/gcc/testsuite/gcc.target/s390/litpool-int.c new file mode 100644 index 00000000000..a6bf0c01f4f --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/litpool-int.c @@ -0,0 +1,12 @@ +/* Test that we do not generate useless LAs. */ + +/* { dg-do compile } */ +/* { dg-options "-march=z10 -O1" } */ + +int a; + +void b() +{ + a /= 100; + /* { dg-final { scan-assembler-not {(?n)\n\tla\t%r\d+,.+\(%r13\)\n} } } */ +} -- 2.19.0