summaryrefslogtreecommitdiff
path: root/debian/patches/pr58595.diff
blob: fd9c7c1f878825c0a96e08dd635b98a19e6333a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# DP: Fix PR target/58595, ARM TLS handling

2014-03-05  Jakub Jelinek  <jakub@redhat.com>
	    Meador Inge  <meadori@codesourcery.com>

	PR target/58595
	* config/arm/arm.c (arm_tls_symbol_p): Remove.
	(arm_legitimize_address): Call legitimize_tls_address for any
	arm_tls_referenced_p expression, handle constant addend.  Call it
	before testing for !TARGET_ARM.
	(thumb_legitimize_address): Don't handle arm_tls_symbol_p here.

	* gcc.dg/tls/pr58595.c: New test.

--- a/src/gcc/config/arm/arm.c
+++ b/src/gcc/config/arm/arm.c
@@ -235,7 +235,6 @@ static tree arm_gimplify_va_arg_expr (tr
 static void arm_option_override (void);
 static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
 static bool arm_cannot_copy_insn_p (rtx);
-static bool arm_tls_symbol_p (rtx x);
 static int arm_issue_rate (void);
 static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
 static bool arm_output_addr_const_extra (FILE *, rtx);
@@ -7336,6 +7335,32 @@ legitimize_tls_address (rtx x, rtx reg)
 rtx
 arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
 {
+  if (arm_tls_referenced_p (x))
+    {
+      rtx addend = NULL;
+
+      if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
+	{
+	  addend = XEXP (XEXP (x, 0), 1);
+	  x = XEXP (XEXP (x, 0), 0);
+	}
+
+      if (GET_CODE (x) != SYMBOL_REF)
+	return x;
+
+      gcc_assert (SYMBOL_REF_TLS_MODEL (x) != 0);
+
+      x = legitimize_tls_address (x, NULL_RTX);
+
+      if (addend)
+	{
+	  x = gen_rtx_PLUS (SImode, x, addend);
+	  orig_x = x;
+	}
+      else
+	return x;
+    }
+
   if (!TARGET_ARM)
     {
       /* TODO: legitimize_address for Thumb2.  */
@@ -7344,9 +7369,6 @@ arm_legitimize_address (rtx x, rtx orig_
       return thumb_legitimize_address (x, orig_x, mode);
     }
 
-  if (arm_tls_symbol_p (x))
-    return legitimize_tls_address (x, NULL_RTX);
-
   if (GET_CODE (x) == PLUS)
     {
       rtx xop0 = XEXP (x, 0);
@@ -7459,9 +7481,6 @@ arm_legitimize_address (rtx x, rtx orig_
 rtx
 thumb_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
 {
-  if (arm_tls_symbol_p (x))
-    return legitimize_tls_address (x, NULL_RTX);
-
   if (GET_CODE (x) == PLUS
       && CONST_INT_P (XEXP (x, 1))
       && (INTVAL (XEXP (x, 1)) >= 32 * GET_MODE_SIZE (mode)
@@ -7756,20 +7775,6 @@ thumb_legitimize_reload_address (rtx *x_
 
 /* Test for various thread-local symbols.  */
 
-/* Return TRUE if X is a thread-local symbol.  */
-
-static bool
-arm_tls_symbol_p (rtx x)
-{
-  if (! TARGET_HAVE_TLS)
-    return false;
-
-  if (GET_CODE (x) != SYMBOL_REF)
-    return false;
-
-  return SYMBOL_REF_TLS_MODEL (x) != 0;
-}
-
 /* Helper for arm_tls_referenced_p.  */
 
 static int
--- a/src/gcc/testsuite/gcc.dg/tls/pr58595.c
+++ b/src/gcc/testsuite/gcc.dg/tls/pr58595.c
@@ -0,0 +1,28 @@
+/* PR target/58595 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-fpic" { target fpic } } */
+/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target sync_int_long } */
+
+struct S { unsigned long a, b; };
+__thread struct S s;
+void bar (unsigned long *);
+
+__attribute__((noinline)) void
+foo (void)
+{
+  int i;
+  for (i = 0; i < 10; i++)
+    __sync_fetch_and_add (&s.b, 1L);
+}
+
+int
+main ()
+{
+  s.b = 12;
+  foo ();
+  if (s.b != 22)
+    __builtin_abort ();
+  return 0;
+}

	Jakub