[Committed] IBM Z: Fix PR96308
Andreas Krebbel
krebbel@linux.ibm.com
Wed Aug 12 06:24:35 GMT 2020
For the testcase a symbol with a TLS reloc and an unary minus is being
generated. The backend didn't handle this correctly.
In s390_cannot_force_const_mem an unary minus on a symbolic constant
is rejected now since gas would not allow this.
legitimize_tls_address now makes the NEG rtx the outermost operation
by pulling it out of the CONST rtx.
Bootstrapped and regression tested on s390x.
Committed to mainline.
gcc/ChangeLog:
PR target/96308
* config/s390/s390.c (s390_cannot_force_const_mem): Reject an
unary minus for everything not being a numeric constant.
(legitimize_tls_address): Move a NEG out of the CONST rtx.
gcc/testsuite/ChangeLog:
PR target/96308
* g++.dg/pr96308.C: New test.
---
gcc/config/s390/s390.c | 25 +++++++++++++++++++++++++
gcc/testsuite/g++.dg/pr96308.C | 7 +++++++
2 files changed, 32 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/pr96308.C
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 22ac5e43121..5488a5dc5e8 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -4106,6 +4106,18 @@ s390_cannot_force_const_mem (machine_mode mode, rtx x)
/* Accept all non-symbolic constants. */
return false;
+ case NEG:
+ /* Accept an unary '-' only on scalar numeric constants. */
+ switch (GET_CODE (XEXP (x, 0)))
+ {
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case CONST_WIDE_INT:
+ return false;
+ default:
+ return true;
+ }
+
case LABEL_REF:
/* Labels are OK iff we are non-PIC. */
return flag_pic != 0;
@@ -5268,6 +5280,7 @@ legitimize_tls_address (rtx addr, rtx reg)
{
switch (XINT (XEXP (addr, 0), 1))
{
+ case UNSPEC_NTPOFF:
case UNSPEC_INDNTPOFF:
new_rtx = addr;
break;
@@ -5290,6 +5303,18 @@ legitimize_tls_address (rtx addr, rtx reg)
new_rtx = force_operand (new_rtx, 0);
}
+ /* (const (neg (unspec (symbol_ref)))) -> (neg (const (unspec (symbol_ref)))) */
+ else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == NEG)
+ {
+ new_rtx = XEXP (XEXP (addr, 0), 0);
+ if (GET_CODE (new_rtx) != SYMBOL_REF)
+ new_rtx = gen_rtx_CONST (Pmode, new_rtx);
+
+ new_rtx = legitimize_tls_address (new_rtx, reg);
+ new_rtx = gen_rtx_NEG (Pmode, new_rtx);
+ new_rtx = force_operand (new_rtx, 0);
+ }
+
else
gcc_unreachable (); /* for now ... */
diff --git a/gcc/testsuite/g++.dg/pr96308.C b/gcc/testsuite/g++.dg/pr96308.C
new file mode 100644
index 00000000000..9009bba5e82
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr96308.C
@@ -0,0 +1,7 @@
+// { dg-do compile }
+// { dg-options "-Os -fno-move-loop-invariants -std=c++11" }
+
+struct NonTrivial3 {
+ ~NonTrivial3();
+};
+void i() { thread_local NonTrivial3 tlarr[10]; }
--
2.25.1
More information about the Gcc-patches
mailing list