Backported 15 patches to 4.6 branch
Jakub Jelinek
jakub@redhat.com
Thu Feb 9 17:43:00 GMT 2012
Hi!
I've backported these patches from trunk to 4.6 branch,
bootstrapped/regtested them on x86_64-linux and i686-linux
and committed. Sorry for the delay.
Jakub
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2011-12-15 Jakub Jelinek <jakub@redhat.com>
PR debug/51517
* tree-ssa-coalesce.c (coalesce_ssa_name): For !optimize, test
!DECL_IGNORED_P instead of !DECL_ARTIFICIAL.
* trans-decl.c (gfc_get_symbol_decl): Don't set DECL_INITAL on span.
(gfc_trans_deferred_vars): Instead add its runtime initialization
here.
--- gcc/tree-ssa-coalesce.c (revision 182361)
+++ gcc/tree-ssa-coalesce.c (revision 182362)
@@ -1373,7 +1373,7 @@ coalesce_ssa_name (void)
if (a
&& SSA_NAME_VAR (a)
- && !DECL_ARTIFICIAL (SSA_NAME_VAR (a))
+ && !DECL_IGNORED_P (SSA_NAME_VAR (a))
&& (!has_zero_uses (a) || !SSA_NAME_IS_DEFAULT_DEF (a)))
{
tree *slot = (tree *) htab_find_slot (ssa_name_hash, a, INSERT);
--- gcc/fortran/trans-decl.c (revision 182361)
+++ gcc/fortran/trans-decl.c (revision 182362)
@@ -1352,7 +1352,6 @@ gfc_get_symbol_decl (gfc_symbol * sym)
gfc_finish_var_decl (span, sym);
TREE_STATIC (span) = TREE_STATIC (decl);
DECL_ARTIFICIAL (span) = 1;
- DECL_INITIAL (span) = build_int_cst (gfc_array_index_type, 0);
GFC_DECL_SPAN (decl) = span;
GFC_TYPE_ARRAY_SPAN (TREE_TYPE (decl)) = span;
@@ -3394,6 +3393,17 @@ gfc_trans_deferred_vars (gfc_symbol * pr
if (sym->assoc)
continue;
+ if (sym->attr.subref_array_pointer
+ && GFC_DECL_SPAN (sym->backend_decl)
+ && !TREE_STATIC (GFC_DECL_SPAN (sym->backend_decl)))
+ {
+ gfc_init_block (&tmpblock);
+ gfc_add_modify (&tmpblock, GFC_DECL_SPAN (sym->backend_decl),
+ build_int_cst (gfc_array_index_type, 0));
+ gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
+ NULL_TREE);
+ }
+
if (sym->attr.dimension)
{
/* Assumed-size Cray pointees need to be treated as AS_EXPLICIT. */
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2011-12-15 Jakub Jelinek <jakub@redhat.com>
PR c/51360
* c-parser.c (c_parser_omp_clause_num_threads,
c_parser_omp_clause_schedule): Call mark_exp_read.
* semantics.c (finish_omp_clauses): For OMP_CLAUSE_NUM_THREADS_EXPR
and OMP_CLAUSE_SCHEDULE_CHUNK_EXPR call mark_rvalue_use.
* gcc.dg/gomp/pr51360.c: New test.
* g++.dg/gomp/pr51360.C: New test.
* g++.dg/gomp/pr51360-2.C: New test.
--- gcc/cp/semantics.c (revision 182380)
+++ gcc/cp/semantics.c (revision 182381)
@@ -4087,6 +4087,8 @@ finish_omp_clauses (tree clauses)
error ("num_threads expression must be integral");
remove = true;
}
+ else
+ OMP_CLAUSE_NUM_THREADS_EXPR (c) = mark_rvalue_use (t);
break;
case OMP_CLAUSE_SCHEDULE:
@@ -4101,6 +4103,8 @@ finish_omp_clauses (tree clauses)
error ("schedule chunk size expression must be integral");
remove = true;
}
+ else
+ OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = mark_rvalue_use (t);
break;
case OMP_CLAUSE_NOWAIT:
--- gcc/c-parser.c (revision 182380)
+++ gcc/c-parser.c (revision 182381)
@@ -9011,6 +9011,7 @@ c_parser_omp_clause_num_threads (c_parse
{
location_t expr_loc = c_parser_peek_token (parser)->location;
tree c, t = c_parser_expression (parser).value;
+ mark_exp_read (t);
t = c_fully_fold (t, false, NULL);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
@@ -9218,6 +9219,7 @@ c_parser_omp_clause_schedule (c_parser *
here = c_parser_peek_token (parser)->location;
t = c_parser_expr_no_commas (parser, NULL).value;
+ mark_exp_read (t);
t = c_fully_fold (t, false, NULL);
if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
--- gcc/testsuite/g++.dg/gomp/pr51360.C (revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr51360.C (revision 182381)
@@ -0,0 +1,28 @@
+// PR c/51360
+// { dg-do compile }
+// { dg-options "-Wunused -W -fopenmp" }
+
+template <typename T>
+void
+foo (T a, T b, T c)
+{
+ T m, n, o, i;
+ m = 6;
+ n = 1;
+ o = 5;
+ a = 6;
+ b = 1;
+ c = 5;
+ #pragma omp parallel for num_threads (m) if (n) schedule (static, o)
+ for (i = 0; i < 10; i++)
+ ;
+ #pragma omp parallel for num_threads (a) if (b) schedule (static, c)
+ for (i = 0; i < 10; i++)
+ ;
+}
+
+void
+bar ()
+{
+ foo (0, 0, 0);
+}
--- gcc/testsuite/gcc.dg/gomp/pr51360.c (revision 0)
+++ gcc/testsuite/gcc.dg/gomp/pr51360.c (revision 182381)
@@ -0,0 +1,21 @@
+/* PR c/51360 */
+/* { dg-do compile } */
+/* { dg-options "-Wunused -W -fopenmp" } */
+
+void
+foo (int a, int b, int c)
+{
+ int m, n, o, i;
+ m = 6;
+ n = 1;
+ o = 5;
+ a = 6;
+ b = 1;
+ c = 5;
+ #pragma omp parallel for num_threads (m) if (n) schedule (static, o)
+ for (i = 0; i < 10; i++)
+ ;
+ #pragma omp parallel for num_threads (a) if (b) schedule (static, c)
+ for (i = 0; i < 10; i++)
+ ;
+}
--- gcc/testsuite/g++.dg/gomp/pr51360-2.C (revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr51360-2.C (revision 182381)
@@ -0,0 +1,21 @@
+/* PR c/51360 */
+/* { dg-do compile } */
+/* { dg-options "-Wunused -W -fopenmp" } */
+
+void
+foo (int a, int b, int c)
+{
+ int m, n, o, i;
+ m = 6;
+ n = 1;
+ o = 5;
+ a = 6;
+ b = 1;
+ c = 5;
+ #pragma omp parallel for num_threads (m) if (n) schedule (static, o)
+ for (i = 0; i < 10; i++)
+ ;
+ #pragma omp parallel for num_threads (a) if (b) schedule (static, c)
+ for (i = 0; i < 10; i++)
+ ;
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-01-26 Jakub Jelinek <jakub@redhat.com>
* make-relative-prefix.c (make_relative_prefix_1): Avoid warning
about using preprocessor directives inside of macro arguments.
2012-01-02 Jakub Jelinek <jakub@redhat.com>
* make-relative-prefix.c (make_relative_prefix_1): Avoid
stack overflow if PATH contains just a single entry and
HOST_EXECUTABLE_SUFFIX needs to be used.
PR driver/48306
* make-relative-prefix.c: Include sys/stat.h.
(make_relative_prefix_1): If access succeeds, check also stat
if nstore is a regular file.
--- libiberty/make-relative-prefix.c (revision 182819)
+++ libiberty/make-relative-prefix.c (revision 183561)
@@ -58,6 +58,9 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#include <string.h>
@@ -245,10 +248,15 @@
{
char *startp, *endp, *nstore;
size_t prefixlen = strlen (temp) + 1;
+ size_t len;
if (prefixlen < 2)
prefixlen = 2;
- nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
+ len = prefixlen + strlen (progname) + 1;
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
+ len += strlen (HOST_EXECUTABLE_SUFFIX);
+#endif
+ nstore = (char *) alloca (len);
startp = endp = temp;
while (1)
@@ -263,7 +271,7 @@
}
else
{
- strncpy (nstore, startp, endp - startp);
+ memcpy (nstore, startp, endp - startp);
if (! IS_DIR_SEPARATOR (endp[-1]))
{
nstore[endp - startp] = DIR_SEPARATOR;
@@ -279,8 +287,14 @@
#endif
)
{
- progname = nstore;
- break;
+#if defined (HAVE_SYS_STAT_H) && defined (S_ISREG)
+ struct stat st;
+ if (stat (nstore, &st) >= 0 && S_ISREG (st.st_mode))
+#endif
+ {
+ progname = nstore;
+ break;
+ }
}
if (*endp == 0)
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-01-03 Jakub Jelinek <jakub@redhat.com>
PR c++/51669
* semantics.c (finish_omp_clauses): Call fold_build_cleanup_point_expr
on OMP_CLAUSE_{IF,NUM_THREADS,SCHEDULE_CHUNK}_EXPR.
* g++.dg/gomp/pr51669.C: New test.
--- gcc/cp/semantics.c (revision 182827)
+++ gcc/cp/semantics.c (revision 182828)
@@ -3804,6 +3804,8 @@ finish_omp_clauses (tree clauses)
t = maybe_convert_cond (t);
if (t == error_mark_node)
remove = true;
+ else if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
OMP_CLAUSE_IF_EXPR (c) = t;
break;
@@ -3818,7 +3820,12 @@ finish_omp_clauses (tree clauses)
remove = true;
}
else
- OMP_CLAUSE_NUM_THREADS_EXPR (c) = mark_rvalue_use (t);
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
+ }
break;
case OMP_CLAUSE_SCHEDULE:
@@ -3834,7 +3841,12 @@ finish_omp_clauses (tree clauses)
remove = true;
}
else
- OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = mark_rvalue_use (t);
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
+ }
break;
case OMP_CLAUSE_NOWAIT:
--- gcc/testsuite/g++.dg/gomp/pr51669.C (revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr51669.C (revision 182828)
@@ -0,0 +1,32 @@
+// PR c++/51669
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+template <typename T> const T & min (const T &, const T &);
+
+void
+f1 ()
+{
+#pragma omp parallel num_threads (min (4, 5))
+ ;
+}
+
+struct A { A (); ~A (); };
+int foo (const A &);
+
+void
+f2 ()
+{
+ int i;
+#pragma omp parallel if (foo (A ())) num_threads (foo (A ()))
+ ;
+#pragma omp task if (foo (A ()))
+ ;
+#pragma omp for schedule (static, foo (A ()))
+ for (i = 0; i < 10; i++)
+ ;
+#pragma omp parallel for schedule (static, foo (A ())) \
+ if (foo (A ())) num_threads (foo (A ()))
+ for (i = 0; i < 10; i++)
+ ;
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-01-04 Jakub Jelinek <jakub@redhat.com>
PR debug/51695
* dwarf2out.c (output_loc_list): For now drop >= 64KB expressions
in .debug_loc on the floor.
* gcc.dg/pr51695.c: New test.
--- gcc/dwarf2out.c (revision 182885)
+++ gcc/dwarf2out.c (revision 182886)
@@ -11164,6 +11164,13 @@ output_loc_list (dw_loc_list_ref list_he
/* Don't output an entry that starts and ends at the same address. */
if (strcmp (curr->begin, curr->end) == 0)
continue;
+ size = size_of_locs (curr->expr);
+ /* If the expression is too large, drop it on the floor. We could
+ perhaps put it into DW_TAG_dwarf_procedure and refer to that
+ in the expression, but >= 64KB expressions for a single value
+ in a single range are unlikely very useful. */
+ if (size > 0xffff)
+ continue;
if (!have_multiple_function_sections)
{
dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
@@ -11182,7 +11189,6 @@ output_loc_list (dw_loc_list_ref list_he
"Location list end address (%s)",
list_head->ll_symbol);
}
- size = size_of_locs (curr->expr);
/* Output the block length for this list of location operations. */
gcc_assert (size <= 0xffff);
--- gcc/testsuite/gcc.dg/pr51695.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr51695.c (revision 182886)
@@ -0,0 +1,52 @@
+/* PR debug/51695 */
+/* { dg-do compile { target { int32plus } } } */
+/* { dg-options "-O2 -g" } */
+
+typedef struct
+{
+ struct { unsigned int t1, t2, t3, t4, t5, t6; } t;
+ int p;
+ struct { double X, Y, Z; } r;
+} T;
+typedef struct { T *h; } S;
+
+static unsigned int v = 0x12345678;
+
+int
+foo (void)
+{
+ v = (v & 0x80000000) ? ((v << 1) ^ 0xa398655d) : (v << 1);
+ return 0;
+}
+
+double
+bar (void)
+{
+ unsigned int o;
+ v = (v & 0x80000000) ? ((v << 1) ^ 0xa398655d) : (v << 1);
+ o = v & 0xffff;
+ return (double) o / 32768.0;
+}
+
+int
+baz (void)
+{
+ foo ();
+ return 0;
+}
+
+void
+test (S *x)
+{
+ T *t = x->h;
+ t->t.t1 = foo ();
+ t->t.t2 = foo ();
+ t->t.t3 = foo ();
+ t->t.t4 = foo ();
+ t->t.t5 = foo ();
+ t->t.t6 = foo ();
+ t->p = baz ();
+ t->r.X = bar ();
+ t->r.Y = bar ();
+ t->r.Z = bar ();
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-01-05 Jakub Jelinek <jakub@redhat.com>
PR middle-end/44777
* profile.c (branch_prob): Split bbs that have exit edge
and need a fake entry edge too.
* gcc.dg/tree-prof/pr44777.c: New test.
--- gcc/profile.c (revision 182919)
+++ gcc/profile.c (revision 182920)
@@ -1040,6 +1040,41 @@ branch_prob (void)
fprintf (dump_file, "Adding fake entry edge to bb %i\n",
bb->index);
make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
+ /* Avoid bbs that have both fake entry edge and also some
+ exit edge. One of those edges wouldn't be added to the
+ spanning tree, but we can't instrument any of them. */
+ if (have_exit_edge || need_exit_edge)
+ {
+ gimple_stmt_iterator gsi;
+ gimple first;
+ tree fndecl;
+
+ gsi = gsi_after_labels (bb);
+ gcc_checking_assert (!gsi_end_p (gsi));
+ first = gsi_stmt (gsi);
+ if (is_gimple_debug (first))
+ {
+ gsi_next_nondebug (&gsi);
+ gcc_checking_assert (!gsi_end_p (gsi));
+ first = gsi_stmt (gsi);
+ }
+ /* Don't split the bbs containing __builtin_setjmp_receiver
+ or __builtin_setjmp_dispatcher calls. These are very
+ special and don't expect anything to be inserted before
+ them. */
+ if (!is_gimple_call (first)
+ || (fndecl = gimple_call_fndecl (first)) == NULL
+ || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL
+ || (DECL_FUNCTION_CODE (fndecl) != BUILT_IN_SETJMP_RECEIVER
+ && (DECL_FUNCTION_CODE (fndecl)
+ != BUILT_IN_SETJMP_DISPATCHER)))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Splitting bb %i after labels\n",
+ bb->index);
+ split_block_after_labels (bb);
+ }
+ }
}
}
--- gcc/testsuite/gcc.dg/tree-prof/pr44777.c (revision 0)
+++ gcc/testsuite/gcc.dg/tree-prof/pr44777.c (revision 182920)
@@ -0,0 +1,43 @@
+/* PR middle-end/44777 */
+/* { dg-options "-O0" } */
+/* A variant of gcc.c-torture/execute/comp-goto-2.c. */
+
+extern void abort (void);
+extern void exit (int);
+
+#ifdef STACK_SIZE
+#define DEPTH ((STACK_SIZE) / 512 + 1)
+#else
+#define DEPTH 1000
+#endif
+
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+int
+x (int a)
+{
+ __label__ xlab;
+ void y (int a)
+ {
+ void *x = &&llab;
+ if (a==-1)
+ goto *x;
+ if (a==0)
+ goto xlab;
+ llab:
+ y (a-1);
+ }
+ y (a);
+ xlab:;
+ return a;
+}
+#endif
+
+int
+main ()
+{
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+ if (x (DEPTH) != DEPTH)
+ abort ();
+#endif
+ exit (0);
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-01-05 Jakub Jelinek <jakub@redhat.com>
PR middle-end/51768
* stmt.c (check_unique_operand_names): Don't ICE during error
reporting if i is from labels chain.
* c-c++-common/pr51768.c: New test.
--- gcc/stmt.c (revision 182920)
+++ gcc/stmt.c (revision 182921)
@@ -1253,11 +1253,11 @@ check_operand_nalternatives (tree output
static bool
check_unique_operand_names (tree outputs, tree inputs, tree labels)
{
- tree i, j;
+ tree i, j, i_name = NULL_TREE;
for (i = outputs; i ; i = TREE_CHAIN (i))
{
- tree i_name = TREE_PURPOSE (TREE_PURPOSE (i));
+ i_name = TREE_PURPOSE (TREE_PURPOSE (i));
if (! i_name)
continue;
@@ -1268,7 +1268,7 @@ check_unique_operand_names (tree outputs
for (i = inputs; i ; i = TREE_CHAIN (i))
{
- tree i_name = TREE_PURPOSE (TREE_PURPOSE (i));
+ i_name = TREE_PURPOSE (TREE_PURPOSE (i));
if (! i_name)
continue;
@@ -1282,7 +1282,7 @@ check_unique_operand_names (tree outputs
for (i = labels; i ; i = TREE_CHAIN (i))
{
- tree i_name = TREE_PURPOSE (i);
+ i_name = TREE_PURPOSE (i);
if (! i_name)
continue;
@@ -1297,8 +1297,7 @@ check_unique_operand_names (tree outputs
return true;
failure:
- error ("duplicate asm operand name %qs",
- TREE_STRING_POINTER (TREE_PURPOSE (TREE_PURPOSE (i))));
+ error ("duplicate asm operand name %qs", TREE_STRING_POINTER (i_name));
return false;
}
--- gcc/testsuite/c-c++-common/pr51768.c (revision 0)
+++ gcc/testsuite/c-c++-common/pr51768.c (revision 182921)
@@ -0,0 +1,25 @@
+/* PR middle-end/51768 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+ asm goto ("" : : : : lab, lab, lab2, lab); /* { dg-error "duplicate asm operand name" } */
+lab:;
+lab2:;
+}
+
+void
+bar (void)
+{
+ asm goto ("" : : [lab] "i" (0) : : lab); /* { dg-error "duplicate asm operand name" } */
+lab:;
+}
+
+void
+baz (void)
+{
+ int x;
+ asm ("" : [lab] "=r" (x) : [lab] "r" (x)); /* { dg-error "duplicate asm operand name" } */
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-01-05 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/51767
* cfgrtl.c (force_nonfallthru_and_redirect): Force addition
of jump_block and add an extra edge for degenerated asm gotos.
* gcc.c-torture/compile/pr51767.c: New test.
--- gcc/cfgrtl.c (revision 182921)
+++ gcc/cfgrtl.c (revision 182922)
@@ -1129,6 +1129,7 @@ force_nonfallthru_and_redirect (edge e,
rtx note;
edge new_edge;
int abnormal_edge_flags = 0;
+ bool asm_goto_edge = false;
int loc;
/* In the case the last instruction is conditional jump to the next
@@ -1208,8 +1209,28 @@ force_nonfallthru_and_redirect (edge e,
}
}
- if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags)
+ /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs
+ don't point to target label. */
+ if (JUMP_P (BB_END (e->src))
+ && target != EXIT_BLOCK_PTR
+ && e->dest == target
+ && (e->flags & EDGE_FALLTHRU)
+ && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
{
+ int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
+
+ for (i = 0; i < n; ++i)
+ if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
+ {
+ asm_goto_edge = true;
+ break;
+ }
+ }
+
+ if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)
+ {
+ gcov_type count = e->count;
+ int probability = e->probability;
/* Create the new structures. */
/* If the old block ended with a tablejump, skip its table
@@ -1220,7 +1241,7 @@ force_nonfallthru_and_redirect (edge e,
note = NEXT_INSN (note);
jump_block = create_basic_block (note, NULL, e->src);
- jump_block->count = e->count;
+ jump_block->count = count;
jump_block->frequency = EDGE_FREQUENCY (e);
jump_block->loop_depth = target->loop_depth;
@@ -1236,13 +1257,27 @@ force_nonfallthru_and_redirect (edge e,
/* Wire edge in. */
new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
- new_edge->probability = e->probability;
- new_edge->count = e->count;
+ new_edge->probability = probability;
+ new_edge->count = count;
/* Redirect old edge. */
redirect_edge_pred (e, jump_block);
e->probability = REG_BR_PROB_BASE;
+ /* If asm goto has any label refs to target's label,
+ add also edge from asm goto bb to target. */
+ if (asm_goto_edge)
+ {
+ new_edge->probability /= 2;
+ new_edge->count /= 2;
+ jump_block->count /= 2;
+ jump_block->frequency /= 2;
+ new_edge = make_edge (new_edge->src, target,
+ e->flags & ~EDGE_FALLTHRU);
+ new_edge->probability = probability - probability / 2;
+ new_edge->count = count - count / 2;
+ }
+
new_bb = jump_block;
}
else
--- gcc/testsuite/gcc.c-torture/compile/pr51767.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr51767.c (revision 182922)
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/51767 */
+
+extern void fn1 (void), fn2 (void);
+
+static inline __attribute__((always_inline)) int
+foo (int *x, long y)
+{
+ asm goto ("" : : "r" (x), "r" (y) : "memory" : lab);
+ return 0;
+lab:
+ return 1;
+}
+
+void
+bar (int *x)
+{
+ if (foo (x, 23))
+ fn1 ();
+ else
+ fn2 ();
+
+ foo (x, 2);
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-01-19 Jakub Jelinek <jakub@redhat.com>
PR libmudflap/40778
* tree-mudflap.c (mf_artificial): New function.
(execute_mudflap_function_ops, execute_mudflap_function_decls,
mx_register_decls, mudflap_enqueue_decl): Use it.
* testsuite/libmudflap.c/fail68-frag.c: New test.
--- gcc/tree-mudflap.c (revision 183306)
+++ gcc/tree-mudflap.c (revision 183307)
@@ -69,6 +69,13 @@ static tree mx_xfn_xform_decls (gimple_s
static gimple_seq mx_register_decls (tree, gimple_seq, location_t);
static unsigned int execute_mudflap_function_decls (void);
+/* Return true if DECL is artificial stub that shouldn't be instrumented by
+ mf. We should instrument clones of non-artificial functions. */
+static inline bool
+mf_artificial (const_tree decl)
+{
+ return DECL_ARTIFICIAL (DECL_ORIGIN (decl));
+}
/* ------------------------------------------------------------------------ */
/* Some generally helpful functions for mudflap instrumentation. */
@@ -412,8 +419,8 @@ execute_mudflap_function_ops (void)
/* Don't instrument functions such as the synthetic constructor
built during mudflap_finish_file. */
- if (mf_marked_p (current_function_decl) ||
- DECL_ARTIFICIAL (current_function_decl))
+ if (mf_marked_p (current_function_decl)
+ || mf_artificial (current_function_decl))
return 0;
push_gimplify_context (&gctx);
@@ -994,8 +1001,8 @@ execute_mudflap_function_decls (void)
/* Don't instrument functions such as the synthetic constructor
built during mudflap_finish_file. */
- if (mf_marked_p (current_function_decl) ||
- DECL_ARTIFICIAL (current_function_decl))
+ if (mf_marked_p (current_function_decl)
+ || mf_artificial (current_function_decl))
return 0;
push_gimplify_context (&gctx);
@@ -1078,7 +1085,7 @@ mx_register_decls (tree decl, gimple_seq
/* Add the __mf_register call at the current appending point. */
if (gsi_end_p (initially_stmts))
{
- if (!DECL_ARTIFICIAL (decl))
+ if (!mf_artificial (decl))
warning (OPT_Wmudflap,
"mudflap cannot track %qE in stub function",
DECL_NAME (decl));
@@ -1249,7 +1256,7 @@ mudflap_enqueue_decl (tree obj)
during mudflap_finish_file (). That would confuse the user,
since the text would refer to variables that don't show up in the
user's source code. */
- if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
+ if (DECL_P (obj) && DECL_EXTERNAL (obj) && mf_artificial (obj))
return;
VEC_safe_push (tree, gc, deferred_static_decls, obj);
--- libmudflap/testsuite/libmudflap.c/fail68-frag.c (revision 0)
+++ libmudflap/testsuite/libmudflap.c/fail68-frag.c (revision 183307)
@@ -0,0 +1,27 @@
+/* PR libmudflap/40778 */
+
+char p[32];
+static int j;
+
+__attribute__((noinline))
+static void foo (int i)
+{
+ if (j++ == 0)
+ p[i + 4] = 12;
+ else
+ p[i - 4] = 13;
+}
+
+int
+main ()
+{
+ foo (30);
+ foo (30);
+ foo (30);
+ return 0;
+}
+
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*name.*p" } */
+/* { dg-do run { xfail *-*-* } } */
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-01-28 Jakub Jelinek <jakub@redhat.com>
PR target/52006
* config/arm/arm.md (pic_add_dot_plus_eight peephole2): Use
arm_general_register_operand predicate for operand 2 instead of
register_operand.
* gcc.target/arm/pr52006.c: New test.
--- gcc/config/arm/arm.md (revision 183660)
+++ gcc/config/arm/arm.md (revision 183661)
@@ -5719,7 +5719,8 @@ (define_peephole2
(const_int 8)
(match_operand 1 "" "")]
UNSPEC_PIC_BASE))
- (set (match_operand:SI 2 "register_operand" "") (mem:SI (match_dup 0)))]
+ (set (match_operand:SI 2 "arm_general_register_operand" "")
+ (mem:SI (match_dup 0)))]
"TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 2)
(mem:SI (unspec:SI [(match_dup 3)
--- gcc/testsuite/gcc.target/arm/pr52006.c (revision 0)
+++ gcc/testsuite/gcc.target/arm/pr52006.c (revision 183661)
@@ -0,0 +1,19 @@
+/* PR target/52006 */
+/* { dg-do compile } */
+/* { dg-options "-march=armv7-a -mfloat-abi=hard -O2 -fPIC" } */
+
+unsigned long a;
+static int b;
+
+void
+foo (void)
+{
+ asm volatile ("" : "=r" (b));
+}
+
+void
+bar (float f)
+{
+ if (f < b / 100.0)
+ a = 1;
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-02-02 Jakub Jelinek <jakub@redhat.com>
PR middle-end/48071
* diagnostic.c (diagnostic_finish): Remove trailing newlines.
--- gcc/diagnostic.c (revision 183846)
+++ gcc/diagnostic.c (revision 183847)
@@ -133,12 +133,12 @@ diagnostic_finish (diagnostic_context *c
/* -Werror was given. */
if (context->warning_as_error_requested)
pp_verbatim (context->printer,
- _("%s: all warnings being treated as errors\n"),
+ _("%s: all warnings being treated as errors"),
progname);
/* At least one -Werror= was given. */
else
pp_verbatim (context->printer,
- _("%s: some warnings being treated as errors\n"),
+ _("%s: some warnings being treated as errors"),
progname);
pp_flush (context->printer);
}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-02-06 Jakub Jelinek <jakub@redhat.com>
PR target/52129
* calls.c (mem_overlaps_already_clobbered_arg_p): If val is
CONST_INT_P, subtract resp. add crtl->args.pretend_args_size to it.
* gcc.c-torture/execute/pr52129.c: New test.
--- gcc/calls.c (revision 183932)
+++ gcc/calls.c (revision 183933)
@@ -1808,6 +1808,11 @@ mem_overlaps_already_clobbered_arg_p (rt
return true;
else
i = INTVAL (val);
+#ifdef STACK_GROWS_DOWNWARD
+ i -= crtl->args.pretend_args_size;
+#else
+ i += crtl->args.pretend_args_size;
+#endif
#ifdef ARGS_GROW_DOWNWARD
i = -i - size;
--- gcc/testsuite/gcc.c-torture/execute/pr52129.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr52129.c (revision 183933)
@@ -0,0 +1,28 @@
+/* PR target/52129 */
+
+extern void abort (void);
+struct S { void *p; unsigned int q; };
+struct T { char a[64]; char b[64]; } t;
+
+__attribute__((noinline, noclone)) int
+foo (void *x, struct S s, void *y, void *z)
+{
+ if (x != &t.a[2] || s.p != &t.b[5] || s.q != 27 || y != &t.a[17] || z != &t.b[17])
+ abort ();
+ return 29;
+}
+
+__attribute__((noinline, noclone)) int
+bar (void *x, void *y, void *z, struct S s, int t, struct T *u)
+{
+ return foo (x, s, &u->a[t], &u->b[t]);
+}
+
+int
+main ()
+{
+ struct S s = { &t.b[5], 27 };
+ if (bar (&t.a[2], (void *) 0, (void *) 0, s, 17, &t) != 29)
+ abort ();
+ return 0;
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-02-07 Jakub Jelinek <jakub@redhat.com>
PR middle-end/52074
* expr.c (expand_expr_addr_expr_1): For CONSTANT_CLASS_P or CONST_DECL
if modifier < EXPAND_SUM call force_operand on the result.
* gcc.c-torture/compile/pr52074.c: New test.
--- gcc/expr.c (revision 183955)
+++ gcc/expr.c (revision 183956)
@@ -7414,7 +7414,12 @@ expand_expr_addr_expr_1 (tree exp, rtx t
generating ADDR_EXPR of something that isn't an LVALUE. The only
exception here is STRING_CST. */
if (CONSTANT_CLASS_P (exp))
- return XEXP (expand_expr_constant (exp, 0, modifier), 0);
+ {
+ result = XEXP (expand_expr_constant (exp, 0, modifier), 0);
+ if (modifier < EXPAND_SUM)
+ result = force_operand (result, target);
+ return result;
+ }
/* Everything must be something allowed by is_gimple_addressable. */
switch (TREE_CODE (exp))
@@ -7433,7 +7438,11 @@ expand_expr_addr_expr_1 (tree exp, rtx t
case CONST_DECL:
/* Expand the initializer like constants above. */
- return XEXP (expand_expr_constant (DECL_INITIAL (exp), 0, modifier), 0);
+ result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
+ 0, modifier), 0);
+ if (modifier < EXPAND_SUM)
+ result = force_operand (result, target);
+ return result;
case REALPART_EXPR:
/* The real part of the complex number is always first, therefore
--- gcc/testsuite/gcc.c-torture/compile/pr52074.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr52074.c (revision 183956)
@@ -0,0 +1,10 @@
+/* PR middle-end/52074 */
+
+struct S { const char *d, *e; } __attribute__((packed));
+
+void
+foo (const char **p, struct S *q)
+{
+ *p = "abcdef";
+ q->d = "ghijk";
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-02-07 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/52060
* combine.c (try_combine): Add i0src_copy and i0src_copy2 variables,
copy i1src to i1src_copy whenever added_sets_2 && i1_feeds_i2_n already
before i1dest -> i1src substitution in newpat, copy i0src to i0src_copy
and/or i0src_copy2 when needed.
* gcc.dg/torture/pr52060.c: New test.
--- gcc/combine.c (revision 183971)
+++ gcc/combine.c (revision 183972)
@@ -2558,8 +2558,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
rtx i3dest_killed = 0;
/* SET_DEST and SET_SRC of I2, I1 and I0. */
rtx i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0;
- /* Copy of SET_SRC of I1, if needed. */
- rtx i1src_copy = 0;
+ /* Copy of SET_SRC of I1 and I0, if needed. */
+ rtx i1src_copy = 0, i0src_copy = 0, i0src_copy2 = 0;
/* Set if I2DEST was reused as a scratch register. */
bool i2scratch = false;
/* The PATTERNs of I0, I1, and I2, or a copy of them in certain cases. */
@@ -3171,6 +3171,11 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
n_occurrences = 0;
subst_low_luid = DF_INSN_LUID (i1);
+ /* If the following substitution will modify I1SRC, make a copy of it
+ for the case where it is substituted for I1DEST in I2PAT later. */
+ if (added_sets_2 && i1_feeds_i2_n)
+ i1src_copy = copy_rtx (i1src);
+
/* If I0 feeds into I1 and I0DEST is in I0SRC, we need to make a unique
copy of I1SRC each time we substitute it, in order to avoid creating
self-referential RTL when we will be substituting I0SRC for I0DEST
@@ -3198,10 +3203,14 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
return 0;
}
- /* If the following substitution will modify I1SRC, make a copy of it
- for the case where it is substituted for I1DEST in I2PAT later. */
- if (i0_feeds_i1_n && added_sets_2 && i1_feeds_i2_n)
- i1src_copy = copy_rtx (i1src);
+ /* If the following substitution will modify I0SRC, make a copy of it
+ for the case where it is substituted for I0DEST in I1PAT later. */
+ if (added_sets_1 && i0_feeds_i1_n)
+ i0src_copy = copy_rtx (i0src);
+ /* And a copy for I0DEST in I2PAT substitution. */
+ if (added_sets_2 && ((i0_feeds_i1_n && i1_feeds_i2_n)
+ || (i0_feeds_i2_n)))
+ i0src_copy2 = copy_rtx (i0src);
n_occurrences = 0;
subst_low_luid = DF_INSN_LUID (i0);
@@ -3267,7 +3276,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
{
rtx t = i1pat;
if (i0_feeds_i1_n)
- t = subst (t, i0dest, i0src, 0, 0);
+ t = subst (t, i0dest, i0src_copy ? i0src_copy : i0src, 0, 0);
XVECEXP (newpat, 0, --total_sets) = t;
}
@@ -3278,7 +3287,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, 0,
i0_feeds_i1_n && i0dest_in_i0src);
if ((i0_feeds_i1_n && i1_feeds_i2_n) || i0_feeds_i2_n)
- t = subst (t, i0dest, i0src, 0, 0);
+ t = subst (t, i0dest, i0src_copy2 ? i0src_copy2 : i0src, 0, 0);
XVECEXP (newpat, 0, --total_sets) = t;
}
--- gcc/testsuite/gcc.dg/torture/pr52060.c (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr52060.c (revision 183972)
@@ -0,0 +1,57 @@
+/* PR rtl-optimization/52060 */
+/* { dg-do run { target int32plus } } */
+
+extern void abort (void);
+union U { float f; unsigned int i; };
+
+static inline __attribute__((always_inline)) unsigned int
+foo (float x)
+{
+ union U u;
+ unsigned int a, b, c;
+ int d;
+ int e;
+ u.f = x;
+ d = ((unsigned) u.i >> 23) & 0xFF;
+ c = d < 126 ? 0 : ~0;
+ e = 127 + 30 - d;
+ a = (u.i << 8) | 0x80000000U;
+ b = a & ((1 << e) - 1);
+ a = a >> e;
+ c &= (b | (a & 2)) ? ~0 : ~1;
+ a = ((a + 1U) >> 1) & c;
+ return a;
+}
+
+__attribute__((noinline)) unsigned int
+bar (float x)
+{
+ unsigned int a, b, c;
+ static const unsigned int d[128] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7
+ };
+ a = foo (1048575.0f * x);
+ c = d[a >> 13];
+ b = (c << 13) | ((a >> (7 - c)) & 0x1fff);
+ return b;
+}
+
+int
+main ()
+{
+ union U u;
+ u.f = 1048575.0f;
+ if (sizeof (u.i) == sizeof (u.f)
+ && u.i == 0x497ffff0U
+ && bar (1.0f) != 65535)
+ abort ();
+ return 0;
+}
-------------- next part --------------
2012-02-09 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-02-08 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/52139
* cfgrtl.c (cfg_layout_merge_blocks): If BB_END
is a BARRIER after emit_insn_after_noloc, move BB_END
to the last non-BARRIER insn before it.
* gcc.dg/pr52139.c: New test.
--- gcc/cfgrtl.c (revision 184004)
+++ gcc/cfgrtl.c (revision 184005)
@@ -2871,6 +2871,11 @@ cfg_layout_merge_blocks (basic_block a,
rtx first = BB_END (a), last;
last = emit_insn_after_noloc (b->il.rtl->header, BB_END (a), a);
+ /* The above might add a BARRIER as BB_END, but as barriers
+ aren't valid parts of a bb, remove_insn doesn't update
+ BB_END if it is a barrier. So adjust BB_END here. */
+ while (BB_END (a) != first && BARRIER_P (BB_END (a)))
+ BB_END (a) = PREV_INSN (BB_END (a));
delete_insn_chain (NEXT_INSN (first), last, false);
b->il.rtl->header = NULL;
}
--- gcc/testsuite/gcc.dg/pr52139.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr52139.c (revision 184005)
@@ -0,0 +1,49 @@
+/* PR rtl-optimization/52139 */
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre" } */
+/* { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre -fpic" { target fpic } } */
+
+void *p;
+
+void
+foo (int a)
+{
+ switch (a)
+ {
+ case 0:
+ a0:
+ case 1:
+ a1:
+ p = &&a1;
+ case 2:
+ a2:
+ p = &&a2;
+ case 3:
+ a3:
+ p = &&a3;
+ case 4:
+ a4:
+ p = &&a4;
+ case 5:
+ a5:
+ p = &&a5;
+ case 6:
+ a6:
+ p = &&a6;
+ case 7:
+ a7:
+ p = &&a7;
+ case 8:
+ a8:
+ p = &&a8;
+ case 9:
+ a9:
+ p = &&a9;
+ case 10:
+ a10:
+ p = &&a10;
+ default:
+ p = &&a0;
+ }
+ goto *p;
+}
More information about the Gcc-patches
mailing list