@@ -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. */
new file mode 100644
@@ -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} } } */
+}