aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2010-12-02 22:33:16 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2010-12-02 22:33:16 +0000
commit205e4c6a4b80b6307b55b74cb69fadf6ac38dcc9 (patch)
tree778ab8a9ab235a0baa62f6a827ed3204d8e5fa5b
parent5b824b7616ae246facc5d5cff8dd2ae8eb6088df (diff)
downloadgcc-205e4c6a4b80b6307b55b74cb69fadf6ac38dcc9.zip
gcc-205e4c6a4b80b6307b55b74cb69fadf6ac38dcc9.tar.gz
gcc-205e4c6a4b80b6307b55b74cb69fadf6ac38dcc9.tar.bz2
re PR target/46685 (New stack alignment failures with -fpic)
PR target/46685 * config/sparc/sparc.c (can_use_mov_pic_label_ref): New predicate. (sparc_expand_move): Call it to decide whether to emit the special mov{si,di}_pic_label_ref patterns. (sparc_legitimize_pic_address): Call it to decide whether to emit the regular PIC sequence for labels. Fix long line. (sparc_file_end): Set is_thunk for the PIC helper. From-SVN: r167395
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/sparc/sparc.c57
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/pr46685.c40
4 files changed, 97 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5bcef5d..fe73581 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2010-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/46685
+ * config/sparc/sparc.c (can_use_mov_pic_label_ref): New predicate.
+ (sparc_expand_move): Call it to decide whether to emit the special
+ mov{si,di}_pic_label_ref patterns.
+ (sparc_legitimize_pic_address): Call it to decide whether to emit
+ the regular PIC sequence for labels. Fix long line.
+ (sparc_file_end): Set is_thunk for the PIC helper.
+
2010-12-02 Eric Botcazou <ebotcazou@adacore.com>
* tree.c (build_range_type_1): Do not SET_TYPE_STRUCTURAL_EQUALITY
@@ -5044,7 +5054,7 @@
2010-11-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46149
- * tree-ssa-structalias.c (get_constraint_for_1): Properly handle
+ * tree-ssa-structalias.c (get_constraint_fop_1): Properly handle
non-indirect MEM_REF variants.
2010-11-02 Richard Guenther <rguenther@suse.de>
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 85387cc..223408d 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1025,6 +1025,36 @@ fp_high_losum_p (rtx op)
return 0;
}
+/* Return true if the address of LABEL can be loaded by means of the
+ mov{si,di}_pic_label_ref patterns in PIC mode. */
+
+static bool
+can_use_mov_pic_label_ref (rtx label)
+{
+ /* VxWorks does not impose a fixed gap between segments; the run-time
+ gap can be different from the object-file gap. We therefore can't
+ assume X - _GLOBAL_OFFSET_TABLE_ is a link-time constant unless we
+ are absolutely sure that X is in the same segment as the GOT.
+ Unfortunately, the flexibility of linker scripts means that we
+ can't be sure of that in general, so assume that GOT-relative
+ accesses are never valid on VxWorks. */
+ if (TARGET_VXWORKS_RTP)
+ return false;
+
+ /* Similarly, if the label is non-local, it might end up being placed
+ in a different section than the current one; now mov_pic_label_ref
+ requires the label and the code to be in the same section. */
+ if (LABEL_REF_NONLOCAL_P (label))
+ return false;
+
+ /* Finally, if we are reordering basic blocks and partition into hot
+ and cold sections, this might happen for any label. */
+ if (flag_reorder_blocks_and_partition)
+ return false;
+
+ return true;
+}
+
/* Expand a move instruction. Return true if all work is done. */
bool
@@ -1059,14 +1089,9 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
if (pic_address_needs_scratch (operands[1]))
operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX);
- /* VxWorks does not impose a fixed gap between segments; the run-time
- gap can be different from the object-file gap. We therefore can't
- assume X - _GLOBAL_OFFSET_TABLE_ is a link-time constant unless we
- are absolutely sure that X is in the same segment as the GOT.
- Unfortunately, the flexibility of linker scripts means that we
- can't be sure of that in general, so assume that _G_O_T_-relative
- accesses are never valid on VxWorks. */
- if (GET_CODE (operands[1]) == LABEL_REF && !TARGET_VXWORKS_RTP)
+ /* We cannot use the mov{si,di}_pic_label_ref patterns in all cases. */
+ if (GET_CODE (operands[1]) == LABEL_REF
+ && can_use_mov_pic_label_ref (operands[1]))
{
if (mode == SImode)
{
@@ -3425,7 +3450,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
if (GET_CODE (orig) == SYMBOL_REF
/* See the comment in sparc_expand_move. */
- || (TARGET_VXWORKS_RTP && GET_CODE (orig) == LABEL_REF))
+ || (GET_CODE (orig) == LABEL_REF && !can_use_mov_pic_label_ref (orig)))
{
rtx pic_ref, address;
rtx insn;
@@ -3478,11 +3503,13 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
}
else
{
- pic_ref = gen_const_mem (Pmode,
- gen_rtx_PLUS (Pmode,
- pic_offset_table_rtx, address));
+ pic_ref
+ = gen_const_mem (Pmode,
+ gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx, address));
insn = emit_move_insn (reg, pic_ref);
}
+
/* Put a REG_EQUAL note on this insn, so that it can be optimized
by loop. */
set_unique_reg_note (insn, REG_EQUAL, orig);
@@ -3520,9 +3547,8 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
return gen_rtx_PLUS (Pmode, base, offset);
}
else if (GET_CODE (orig) == LABEL_REF)
- /* ??? Why do we do this? */
- /* Now movsi_pic_label_ref uses it, but we ought to be checking that
- the register is live instead, in case it is eliminated. */
+ /* ??? We ought to be checking that the register is live instead, in case
+ it is eliminated. */
crtl->uses_pic_offset_table = 1;
return orig;
@@ -9453,6 +9479,7 @@ sparc_file_end (void)
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (decl) = 1;
allocate_struct_function (decl, true);
+ cfun->is_thunk = 1;
current_function_decl = decl;
init_varasm_status ();
assemble_start_function (decl, name);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3eeee83..71faa57 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2010-11-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/pr46685.c: New test.
+
2010-12-02 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/45199
diff --git a/gcc/testsuite/gcc.dg/pr46685.c b/gcc/testsuite/gcc.dg/pr46685.c
new file mode 100644
index 0000000..6277bcc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr46685.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target freorder } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -freorder-blocks-and-partition -fpic" } */
+
+__attribute__((noinline, noclone))
+void bar (void *x)
+{
+ asm volatile ("" : : "r" (x) : "memory");
+}
+
+__attribute__((noinline, noclone))
+void baz (void)
+{
+ asm volatile ("" : : : "memory");
+}
+
+__attribute__((noinline, noclone))
+int foo (int x)
+{
+ __label__ lab;
+ if (__builtin_expect (x, 0))
+ {
+ lab:
+ baz ();
+ return 2;
+ }
+ bar (&&lab);
+ return 1;
+}
+
+int
+main (void)
+{
+ int x, i;
+ asm volatile ("" : "=r" (x) : "0" (0));
+ for (i = 0; i < 1000000; i++)
+ foo (x);
+ return 0;
+}