Bootstrapped and regtested on s390x-redhat-linux. By the time peephole optimizations run, we've already made up our mind whether to use base-register or relative addressing for literal pool entries. LT(G) supports only base-register addressing, and so it is too late to convert L(G)RL + compare to LT(G). This change should not make the code worse unless building with e.g. -fno-dce, since comparing literal pool entries to zero should be optimized away during earlier passes.
gcc/ChangeLog: 2018-11-19 Ilya Leoshkevich <i...@linux.ibm.com> PR target/88083 * config/s390/s390.md: Skip LT(G) peephole when literal pool is involved. * rtl.h (contains_constant_pool_address_p): New function. * rtlanal.c (contains_constant_pool_address_p): Likewise. gcc/testsuite/ChangeLog: 2018-11-19 Ilya Leoshkevich <i...@linux.ibm.com> PR target/88083 * gcc.target/s390/pr88083.c: New test. --- gcc/config/s390/s390.md | 3 ++- gcc/rtl.h | 1 + gcc/rtlanal.c | 14 ++++++++++++++ gcc/testsuite/gcc.target/s390/pr88083.c | 9 +++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/s390/pr88083.c diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 7a556d40224..721222d221f 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -941,7 +941,8 @@ (compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))] "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM && GENERAL_REG_P (operands[0]) - && satisfies_constraint_T (operands[2])" + && satisfies_constraint_T (operands[2]) + && !contains_constant_pool_address_p (operands[2])" [(parallel [(set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 2) (match_dup 1))) diff --git a/gcc/rtl.h b/gcc/rtl.h index 68d3ceab29f..4f28afcf841 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -3385,6 +3385,7 @@ extern void set_insn_deleted (rtx_insn *); extern rtx single_set_2 (const rtx_insn *, const_rtx); extern bool contains_symbol_ref_p (const_rtx); extern bool contains_symbolic_reference_p (const_rtx); +extern bool contains_constant_pool_address_p (const_rtx); /* Handle the cheap and common cases inline for performance. */ diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index e8b6b9c7a42..0bae21e14c5 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -6550,6 +6550,20 @@ contains_symbolic_reference_p (const_rtx x) return false; } +/* Return true if RTL X contains a constant pool address. */ + +bool +contains_constant_pool_address_p (const_rtx x) +{ + subrtx_iterator::array_type array; + FOR_EACH_SUBRTX (iter, array, x, ALL) + if (SYMBOL_REF_P (*iter) && CONSTANT_POOL_ADDRESS_P (*iter)) + return true; + + return false; +} + + /* Return true if X contains a thread-local symbol. */ bool diff --git a/gcc/testsuite/gcc.target/s390/pr88083.c b/gcc/testsuite/gcc.target/s390/pr88083.c new file mode 100644 index 00000000000..d5e530eef83 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr88083.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-fno-sched-last-insn-heuristic -fno-dce -march=z196 -O2" } */ + +void *a, *b; + +void c(void) +{ + __builtin_memcpy(a, b, -1); /* { dg-warning "exceeds maximum object size" } */ +} -- 2.19.1