aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99521.patch
blob: 6d2d75bf913299d0d53eda13b0c82da012e947d0 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
2011-07-08  Richard Sandiford  <rdsandiford@googlemail.com>

	gcc/
	* builtins.c (get_object_alignment): Fix comment.
	* fold-const.c (get_pointer_modulus_and_residue): Remove
	allow_func_align.  Use get_object_alignment.
	(fold_binary_loc): Update caller.

2011-07-08  Richard Sandiford  <rdsandiford@googlemail.com>

	gcc/
	Backport from mainline:

	2011-06-29  Richard Sandiford  <richard.sandiford@linaro.org>

	PR tree-optimization/49545
	* builtins.c (get_object_alignment_1): Update function comment.
	Do not use DECL_ALIGN for functions, but test
	TARGET_PTRMEMFUNC_VBIT_LOCATION instead.
	* fold-const.c (get_pointer_modulus_and_residue): Don't check
	for functions here.

	gcc/testsuite/
	Backport from mainline:

	2011-06-29  Richard Sandiford  <richard.sandiford@linaro.org>

	* gcc.dg/torture/pr49169.c: Restrict to ARM and MIPS targets.

2011-07-08  Richard Sandiford  <richard.sandiford@linaro.org>

	gcc/
	Backport from mainline:

	2011-07-27  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/49169
	* fold-const.c (get_pointer_modulus_and_residue): Don't rely on
	the alignment of function decls.

	gcc/testsuite/
	Backport from mainline:

	2011-07-27  Michael Hope  <michael.hope@linaro.org>
		    Richard Sandiford  <richard.sandiford@linaro.org>

	PR tree-optimization/49169
	* gcc.dg/torture/pr49169.c: New test.

=== modified file 'gcc/builtins.c'
--- old/gcc/builtins.c	2011-01-06 11:02:44 +0000
+++ new/gcc/builtins.c	2011-06-29 09:59:48 +0000
@@ -263,7 +263,14 @@
 
 /* Return the alignment in bits of EXP, an object.
    Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
-   guessed alignment e.g. from type alignment.  */
+   guessed alignment e.g. from type alignment.
+
+   Note that the address (and thus the alignment) computed here is based
+   on the address to which a symbol resolves, whereas DECL_ALIGN is based
+   on the address at which an object is actually located.  These two
+   addresses are not always the same.  For example, on ARM targets,
+   the address &foo of a Thumb function foo() has the lowest bit set,
+   whereas foo() itself starts on an even address.  */
 
 int
 get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
@@ -327,7 +334,21 @@
     exp = DECL_INITIAL (exp);
   if (DECL_P (exp)
       && TREE_CODE (exp) != LABEL_DECL)
-    align = MIN (inner, DECL_ALIGN (exp));
+    {
+      if (TREE_CODE (exp) == FUNCTION_DECL)
+	{
+	  /* Function addresses can encode extra information besides their
+	     alignment.  However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
+	     allows the low bit to be used as a virtual bit, we know
+	     that the address itself must be 2-byte aligned.  */
+	  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
+	    align = 2 * BITS_PER_UNIT;
+	  else
+	    align = BITS_PER_UNIT;
+	}
+      else
+	align = MIN (inner, DECL_ALIGN (exp));
+    }
 #ifdef CONSTANT_ALIGNMENT
   else if (CONSTANT_CLASS_P (exp))
     align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));

=== modified file 'gcc/fold-const.c'
--- old/gcc/fold-const.c	2011-05-05 14:28:53 +0000
+++ new/gcc/fold-const.c	2011-07-08 12:54:44 +0000
@@ -10030,15 +10030,10 @@
    0 <= N < M as is common.  In general, the precise value of P is unknown.
    M is chosen as large as possible such that constant N can be determined.
 
-   Returns M and sets *RESIDUE to N.
-
-   If ALLOW_FUNC_ALIGN is true, do take functions' DECL_ALIGN_UNIT into
-   account.  This is not always possible due to PR 35705.
- */
+   Returns M and sets *RESIDUE to N.  */
 
 static unsigned HOST_WIDE_INT
-get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue,
-				 bool allow_func_align)
+get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue)
 {
   enum tree_code code;
 
@@ -10068,9 +10063,8 @@
 	    }
 	}
 
-      if (DECL_P (expr)
-	  && (allow_func_align || TREE_CODE (expr) != FUNCTION_DECL))
-	return DECL_ALIGN_UNIT (expr);
+      if (DECL_P (expr))
+	return get_object_alignment (expr, BITS_PER_UNIT, ~0U) / BITS_PER_UNIT;
     }
   else if (code == POINTER_PLUS_EXPR)
     {
@@ -10080,8 +10074,7 @@
 
       op0 = TREE_OPERAND (expr, 0);
       STRIP_NOPS (op0);
-      modulus = get_pointer_modulus_and_residue (op0, residue,
-						 allow_func_align);
+      modulus = get_pointer_modulus_and_residue (op0, residue);
 
       op1 = TREE_OPERAND (expr, 1);
       STRIP_NOPS (op1);
@@ -11801,8 +11794,7 @@
 	  unsigned HOST_WIDE_INT modulus, residue;
 	  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (arg1);
 
-	  modulus = get_pointer_modulus_and_residue (arg0, &residue,
-						     integer_onep (arg1));
+	  modulus = get_pointer_modulus_and_residue (arg0, &residue);
 
 	  /* This works because modulus is a power of 2.  If this weren't the
 	     case, we'd have to replace it by its greatest power-of-2

=== added file 'gcc/testsuite/gcc.dg/torture/pr49169.c'
--- old/gcc/testsuite/gcc.dg/torture/pr49169.c	1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.dg/torture/pr49169.c	2011-06-29 09:59:48 +0000
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { arm*-*-* || mips*-*-* } } } */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+int
+main (void)
+{
+  void *p = main;
+  if ((intptr_t) p & 1)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "abort" } } */