gcc-4_9-branch backports
Jakub Jelinek
jakub@redhat.com
Thu Feb 11 09:49:00 GMT 2016
Hi!
I've committed following backports of my trunk commits to gcc-4_9-branch
after bootstrapping/regtesting them on x86_64-linux and i686-linux.
Jakub
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2015-11-19 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/60736
* include/cpplib.h (cpp_errno_filename): New prototype.
* errors.c (cpp_errno): Don't handle msgid "" specially, use
_(msgid) instead of msgid as argument to cpp_error.
(cpp_errno_filename): New function.
* files.c (read_file_guts): Use cpp_errno_filename instead of
cpp_errno.
(open_file_failed): Likewise. Use file->name if file->path is NULL
in diagnostics.
--- libcpp/include/cpplib.h (revision 230590)
+++ libcpp/include/cpplib.h (revision 230591)
@@ -986,6 +986,9 @@ extern bool cpp_warning_syshdr (cpp_read
/* Output a diagnostic with "MSGID: " preceding the
error string of errno. No location is printed. */
extern bool cpp_errno (cpp_reader *, int, const char *msgid);
+/* Similarly, but with "FILENAME: " instead of "MSGID: ", where
+ the filename is not localized. */
+extern bool cpp_errno_filename (cpp_reader *, int, const char *filename);
/* Same as cpp_error, except additionally specifies a position as a
(translation unit) physical line and physical column. If the line is
--- libcpp/files.c (revision 230590)
+++ libcpp/files.c (revision 230591)
@@ -715,7 +715,7 @@ read_file_guts (cpp_reader *pfile, _cpp_
if (count < 0)
{
- cpp_errno (pfile, CPP_DL_ERROR, file->path);
+ cpp_errno_filename (pfile, CPP_DL_ERROR, file->path);
free (buf);
return false;
}
@@ -1053,7 +1053,8 @@ open_file_failed (cpp_reader *pfile, _cp
/* If the preprocessor output (other than dependency information) is
being used, we must also flag an error. */
if (CPP_OPTION (pfile, deps.need_preprocessor_output))
- cpp_errno (pfile, CPP_DL_FATAL, file->path);
+ cpp_errno_filename (pfile, CPP_DL_FATAL,
+ file->path ? file->path : file->name);
}
else
{
@@ -1067,9 +1068,11 @@ open_file_failed (cpp_reader *pfile, _cp
if (CPP_OPTION (pfile, deps.style) == DEPS_NONE
|| print_dep
|| CPP_OPTION (pfile, deps.need_preprocessor_output))
- cpp_errno (pfile, CPP_DL_FATAL, file->path);
+ cpp_errno_filename (pfile, CPP_DL_FATAL,
+ file->path ? file->path : file->name);
else
- cpp_errno (pfile, CPP_DL_WARNING, file->path);
+ cpp_errno_filename (pfile, CPP_DL_WARNING,
+ file->path ? file->path : file->name);
}
}
--- libcpp/errors.c (revision 230590)
+++ libcpp/errors.c (revision 230591)
@@ -230,8 +230,18 @@ cpp_warning_with_line_syshdr (cpp_reader
bool
cpp_errno (cpp_reader *pfile, int level, const char *msgid)
{
- if (msgid[0] == '\0')
- msgid = _("stdout");
+ return cpp_error (pfile, level, "%s: %s", _(msgid), xstrerror (errno));
+}
+
+/* Print a warning or error, depending on the value of LEVEL. Include
+ information from errno. Unlike cpp_errno, the argument is a filename
+ that is not localized, but "" is replaced with localized "stdout". */
+
+bool
+cpp_errno_filename (cpp_reader *pfile, int level, const char *filename)
+{
+ if (filename[0] == '\0')
+ filename = _("stdout");
- return cpp_error (pfile, level, "%s: %s", msgid, xstrerror (errno));
+ return cpp_error (pfile, level, "%s: %s", filename, xstrerror (errno));
}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2015-11-19 Jakub Jelinek <jakub@redhat.com>
PR target/67770
* config/i386/i386.md (simple_return): Disable if
ix86_static_chain_on_stack is true.
* gcc.target/i386/pr67770.c: New test.
--- gcc/config/i386/i386.md (revision 230592)
+++ gcc/config/i386/i386.md (revision 230593)
@@ -12203,10 +12203,14 @@ (define_expand "return"
;; We need to disable this for TARGET_SEH, as otherwise
;; shrink-wrapped prologue gets enabled too. This might exceed
;; the maximum size of prologue in unwind information.
+;; Also disallow shrink-wrapping if using stack slot to pass the
+;; static chain pointer - the first instruction has to be pushl %esi
+;; and it can't be moved around, as we use alternate entry points
+;; in that case.
(define_expand "simple_return"
[(simple_return)]
- "!TARGET_SEH"
+ "!TARGET_SEH && !ix86_static_chain_on_stack"
{
if (crtl->args.pops_args)
{
--- gcc/testsuite/gcc.target/i386/pr67770.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/pr67770.c (revision 230593)
@@ -0,0 +1,40 @@
+/* PR target/67770 */
+/* { dg-do run { target ia32 } } */
+/* { dg-require-effective-target trampolines } */
+/* { dg-options "-O2" } */
+
+#ifndef NO_TRAMPOLINES
+__attribute__ ((noinline)) void
+foo (int i, void (* __attribute__ ((regparm (3))) bar) (int))
+{
+ bar (i);
+}
+#endif
+
+int
+main ()
+{
+#ifndef NO_TRAMPOLINES
+ int p = 0;
+
+ __attribute__ ((regparm (3), noinline)) void
+ bar (int i)
+ {
+ if (__builtin_expect (i, 0))
+ ++p;
+ }
+
+ foo (0, bar);
+ bar (0);
+
+ if (p != 0)
+ __builtin_abort ();
+
+ foo (1, bar);
+ bar (1);
+
+ if (p != 2)
+ __builtin_abort ();
+#endif
+ return 0;
+}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2015-11-21 Jakub Jelinek <jakub@redhat.com>
PR debug/66432
* tree-inline.c (copy_debug_stmt): If
gimple_debug_source_bind_get_value is DECL_ORIGIN of a PARM_DECL
in decl_debug_args, don't call remap_gimple_op_r on it.
* gcc.dg/debug/pr66432.c: New test.
--- gcc/tree-inline.c (revision 230701)
+++ gcc/tree-inline.c (revision 230702)
@@ -2864,8 +2864,6 @@ copy_debug_stmt (gdebug *stmt, copy_body
else if (gimple_debug_source_bind_p (stmt))
{
gimple_debug_source_bind_set_var (stmt, t);
- walk_tree (gimple_debug_source_bind_get_value_ptr (stmt),
- remap_gimple_op_r, &wi, NULL);
/* When inlining and source bind refers to one of the optimized
away parameters, change the source bind into normal debug bind
referring to the corresponding DEBUG_EXPR_DECL that should have
@@ -2889,7 +2887,10 @@ copy_debug_stmt (gdebug *stmt, copy_body
break;
}
}
- }
+ }
+ if (gimple_debug_source_bind_p (stmt))
+ walk_tree (gimple_debug_source_bind_get_value_ptr (stmt),
+ remap_gimple_op_r, &wi, NULL);
}
processing_debug_stmt = 0;
--- gcc/testsuite/gcc.dg/debug/pr66432.c (revision 0)
+++ gcc/testsuite/gcc.dg/debug/pr66432.c (revision 230702)
@@ -0,0 +1,19 @@
+/* PR debug/66432 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+extern void baz (const char *, const char *) __attribute__ ((__noreturn__));
+
+void
+foo (int x, int y[x][x])
+{
+ if (x < 2)
+ baz ("", "");
+}
+
+void
+bar (void)
+{
+ int z[2][2] = { { 1, 2 }, { 3, 4 } };
+ foo (2, z);
+}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2015-12-03 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/57580
* c-ppoutput.c (print): Change printed field to bool.
(init_pp_output): Set print.printed to false instead of 0.
(scan_translation_unit): Fix up formatting. Set print.printed
to true after printing something other than newline.
(scan_translation_unit_trad): Set print.printed to true instead of 1.
(maybe_print_line_1): Set print.printed to false instead of 0.
(print_line_1): Likewise.
(do_line_change): Set print.printed to true instead of 1.
(cb_define, dump_queued_macros, cb_include, cb_def_pragma,
dump_macro): Set print.printed to false after printing newline.
* c-c++-common/cpp/pr57580.c: New test.
* c-c++-common/gomp/pr57580.c: New test.
--- gcc/c-family/c-ppoutput.c (revision 231212)
+++ gcc/c-family/c-ppoutput.c (revision 231213)
@@ -33,7 +33,7 @@ static struct
const cpp_token *prev; /* Previous token. */
const cpp_token *source; /* Source token for spacing. */
int src_line; /* Line number currently being written. */
- unsigned char printed; /* Nonzero if something output at line. */
+ bool printed; /* True if something output at line. */
bool first_time; /* pp_file_change hasn't been called yet. */
const char *src_file; /* Current source file. */
} print;
@@ -151,7 +151,7 @@ init_pp_output (FILE *out_stream)
/* Initialize the print structure. */
print.src_line = 1;
- print.printed = 0;
+ print.printed = false;
print.prev = 0;
print.outf = out_stream;
print.first_time = 1;
@@ -202,12 +202,16 @@ scan_translation_unit (cpp_reader *pfile
{
do_line_change (pfile, token, loc, false);
putc (' ', print.outf);
+ print.printed = true;
}
else if (print.source->flags & PREV_WHITE
|| (print.prev
&& cpp_avoid_paste (pfile, print.prev, token))
|| (print.prev == NULL && token->type == CPP_HASH))
- putc (' ', print.outf);
+ {
+ putc (' ', print.outf);
+ print.printed = true;
+ }
}
else if (token->flags & PREV_WHITE)
{
@@ -218,6 +222,7 @@ scan_translation_unit (cpp_reader *pfile
&& !in_pragma)
do_line_change (pfile, token, loc, false);
putc (' ', print.outf);
+ print.printed = true;
}
avoid_paste = false;
@@ -235,7 +240,7 @@ scan_translation_unit (cpp_reader *pfile
fprintf (print.outf, "%s %s", space, name);
else
fprintf (print.outf, "%s", name);
- print.printed = 1;
+ print.printed = true;
in_pragma = true;
}
else if (token->type == CPP_PRAGMA_EOL)
@@ -246,9 +251,9 @@ scan_translation_unit (cpp_reader *pfile
else
{
if (cpp_get_options (parse_in)->debug)
- linemap_dump_location (line_table, token->src_loc,
- print.outf);
+ linemap_dump_location (line_table, token->src_loc, print.outf);
cpp_output_token (token, print.outf);
+ print.printed = true;
}
/* CPP_COMMENT tokens and raw-string literal tokens can
@@ -298,7 +303,7 @@ scan_translation_unit_trad (cpp_reader *
size_t len = pfile->out.cur - pfile->out.base;
maybe_print_line (pfile->out.first_line);
fwrite (pfile->out.base, 1, len, print.outf);
- print.printed = 1;
+ print.printed = true;
if (!CPP_OPTION (pfile, discard_comments))
account_for_newlines (pfile->out.base, len);
}
@@ -319,7 +324,7 @@ maybe_print_line_1 (source_location src_
{
putc ('\n', stream);
print.src_line++;
- print.printed = 0;
+ print.printed = false;
}
if (!flag_no_line_commands
@@ -360,7 +365,7 @@ print_line_1 (source_location src_loc, c
/* End any previous line of text. */
if (print.printed)
putc ('\n', stream);
- print.printed = 0;
+ print.printed = false;
if (!flag_no_line_commands)
{
@@ -429,7 +434,7 @@ do_line_change (cpp_reader *pfile, const
if (!CPP_OPTION (pfile, traditional))
{
int spaces = LOCATION_COLUMN (src_loc) - 2;
- print.printed = 1;
+ print.printed = true;
while (-- spaces >= 0)
putc (' ', print.outf);
@@ -470,6 +475,7 @@ cb_define (cpp_reader *pfile, source_loc
fputs ((const char *) NODE_NAME (node), print.outf);
putc ('\n', print.outf);
+ print.printed = false;
linemap_resolve_location (line_table, line,
LRK_MACRO_DEFINITION_LOCATION,
&map);
@@ -521,7 +527,7 @@ dump_queued_macros (cpp_reader *pfile AT
{
putc ('\n', print.outf);
print.src_line++;
- print.printed = 0;
+ print.printed = false;
}
for (q = define_queue; q;)
@@ -530,6 +536,7 @@ dump_queued_macros (cpp_reader *pfile AT
fputs ("#define ", print.outf);
fputs (q->macro, print.outf);
putc ('\n', print.outf);
+ print.printed = false;
print.src_line++;
oq = q;
q = q->next;
@@ -573,6 +580,7 @@ cb_include (cpp_reader *pfile ATTRIBUTE_
}
putc ('\n', print.outf);
+ print.printed = false;
print.src_line++;
}
@@ -638,6 +646,7 @@ cb_def_pragma (cpp_reader *pfile, source
maybe_print_line (line);
fputs ("#pragma ", print.outf);
cpp_output_line (pfile, print.outf);
+ print.printed = false;
print.src_line++;
}
@@ -651,6 +660,7 @@ dump_macro (cpp_reader *pfile, cpp_hashn
fputs ((const char *) cpp_macro_definition (pfile, node),
print.outf);
putc ('\n', print.outf);
+ print.printed = false;
print.src_line++;
}
--- gcc/testsuite/c-c++-common/cpp/pr57580.c (revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr57580.c (revision 231213)
@@ -0,0 +1,9 @@
+/* PR preprocessor/57580 */
+/* { dg-do compile } */
+/* { dg-options "-save-temps" } */
+
+#define MSG \
+ _Pragma("message(\"message0\")") \
+ _Pragma("message(\"message1\")")
+MSG /* { dg-message "message0" } */
+/* { dg-message "message1" "" { target *-*-* } 8 } */
--- gcc/testsuite/c-c++-common/gomp/pr57580.c (revision 0)
+++ gcc/testsuite/c-c++-common/gomp/pr57580.c (revision 231213)
@@ -0,0 +1,36 @@
+/* PR preprocessor/57580 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -save-temps -fdump-tree-gimple" } */
+
+#define PS \
+ _Pragma("omp parallel num_threads(2)") \
+ { \
+ _Pragma("omp single") \
+ { \
+ ret = 0; \
+ } \
+ }
+
+int
+main ()
+{
+ int ret;
+ _Pragma("omp parallel num_threads(3)")
+ {
+ _Pragma("omp single")
+ {
+ ret = 0;
+ }
+ }
+ _Pragma("omp parallel num_threads(4)") { _Pragma("omp single") { ret = 0; } }
+ { _Pragma("omp parallel num_threads(5)") { _Pragma("omp single") { ret = 0; } } }
+ PS
+ PS
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(2\\)" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(3\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(4\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(5\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp single" 5 "gimple" } } */
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2015-12-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/68680
* calls.c (special_function_p): Return ECF_MAY_BE_ALLOCA for
BUILT_IN_ALLOCA{,_WITH_ALIGN}. Don't check for __builtin_alloca
by name.
* gcc.target/i386/pr68680.c: New test.
--- gcc/calls.c (revision 231278)
+++ gcc/calls.c (revision 231279)
@@ -521,12 +521,9 @@ special_function_p (const_tree fndecl, i
/* We assume that alloca will always be called by name. It
makes no sense to pass it as a pointer-to-function to
anything that does not understand its behavior. */
- if (((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6
- && name[0] == 'a'
- && ! strcmp (name, "alloca"))
- || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16
- && name[0] == '_'
- && ! strcmp (name, "__builtin_alloca"))))
+ if (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6
+ && name[0] == 'a'
+ && ! strcmp (name, "alloca"))
flags |= ECF_MAY_BE_ALLOCA;
/* Disregard prefix _, __, __x or __builtin_. */
@@ -572,6 +569,17 @@ special_function_p (const_tree fndecl, i
flags |= ECF_NORETURN;
}
+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_ALLOCA:
+ case BUILT_IN_ALLOCA_WITH_ALIGN:
+ flags |= ECF_MAY_BE_ALLOCA;
+ break;
+ default:
+ break;
+ }
+
return flags;
}
--- gcc/testsuite/gcc.target/i386/pr68680.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/pr68680.c (revision 231279)
@@ -0,0 +1,15 @@
+/* PR tree-optimization/68680 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-protector-strong" } */
+
+int foo (char *);
+
+int
+bar (unsigned long x)
+{
+ char a[x];
+ return foo (a);
+}
+
+/* Verify that this function is stack protected. */
+/* { dg-final { scan-assembler "stack_chk_fail" } } */
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2015-12-10 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/68376
PR rtl-optimization/68670
* ifcvt.c (noce_try_abs): For one_cmpl allow < 0, >= 0
or > -1 conditions regardless of negate, and disallow
all other conditions.
* gcc.c-torture/execute/pr68376-2.c (f5, f6, f7, f8): New
tests.
(main): Call them.
* gcc.dg/pr68670-1.c: New test.
* gcc.dg/pr68670-2.c: New test.
2015-11-19 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/68376
* ifcvt.c (noce_try_abs): Disable one_cmpl optimization if
encountering x <= 0 ? ~x : x or x > 0 ? ~x : x.
* gcc.c-torture/execute/pr68376-1.c: New test.
* gcc.c-torture/execute/pr68376-2.c: New test.
--- gcc/ifcvt.c (revision 230595)
+++ gcc/ifcvt.c (revision 231526)
@@ -2071,12 +2071,26 @@ noce_try_abs (struct noce_if_info *if_in
/* Work around funny ideas get_condition has wrt canonicalization.
Note that these rtx constants are known to be CONST_INT, and
- therefore imply integer comparisons. */
+ therefore imply integer comparisons.
+ The one_cmpl case is more complicated, as we want to handle
+ only x < 0 ? ~x : x or x >= 0 ? x : ~x to one_cmpl_abs (x)
+ and x < 0 ? x : ~x or x >= 0 ? ~x : x to ~one_cmpl_abs (x),
+ but not other cases (x > -1 is equivalent of x >= 0). */
if (c == constm1_rtx && GET_CODE (cond) == GT)
;
else if (c == const1_rtx && GET_CODE (cond) == LT)
- ;
- else if (c != CONST0_RTX (GET_MODE (b)))
+ {
+ if (one_cmpl)
+ return FALSE;
+ }
+ else if (c == CONST0_RTX (GET_MODE (b)))
+ {
+ if (one_cmpl
+ && GET_CODE (cond) != GE
+ && GET_CODE (cond) != LT)
+ return FALSE;
+ }
+ else
return FALSE;
/* Determine what sort of operation this is. */
--- gcc/testsuite/gcc.c-torture/execute/pr68376-1.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr68376-1.c (revision 230596)
@@ -0,0 +1,24 @@
+/* PR rtl-optimization/68376 */
+
+int a, b, c = 1;
+signed char d;
+
+int
+main ()
+{
+ for (; a < 1; a++)
+ for (; b < 1; b++)
+ {
+ signed char e = ~d;
+ if (d < 1)
+ e = d;
+ d = e;
+ if (!c)
+ __builtin_abort ();
+ }
+
+ if (d != 0)
+ __builtin_abort ();
+
+ return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr68376-2.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr68376-2.c (revision 231526)
@@ -0,0 +1,73 @@
+/* PR rtl-optimization/68376 */
+
+extern void abort (void);
+
+__attribute__((noinline, noclone)) int
+f1 (int x)
+{
+ return x < 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f2 (int x)
+{
+ return x < 0 ? x : ~x;
+}
+
+__attribute__((noinline, noclone)) int
+f3 (int x)
+{
+ return x <= 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f4 (int x)
+{
+ return x <= 0 ? x : ~x;
+}
+
+__attribute__((noinline, noclone)) int
+f5 (int x)
+{
+ return x >= 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f6 (int x)
+{
+ return x >= 0 ? x : ~x;
+}
+
+__attribute__((noinline, noclone)) int
+f7 (int x)
+{
+ return x > 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f8 (int x)
+{
+ return x > 0 ? x : ~x;
+}
+
+int
+main ()
+{
+ if (f1 (5) != 5 || f1 (-5) != 4 || f1 (0) != 0)
+ abort ();
+ if (f2 (5) != -6 || f2 (-5) != -5 || f2 (0) != -1)
+ abort ();
+ if (f3 (5) != 5 || f3 (-5) != 4 || f3 (0) != -1)
+ abort ();
+ if (f4 (5) != -6 || f4 (-5) != -5 || f4 (0) != 0)
+ abort ();
+ if (f5 (5) != -6 || f5 (-5) != -5 || f5 (0) != -1)
+ abort ();
+ if (f6 (5) != 5 || f6 (-5) != 4 || f6 (0) != 0)
+ abort ();
+ if (f7 (5) != -6 || f7 (-5) != -5 || f7 (0) != 0)
+ abort ();
+ if (f8 (5) != 5 || f8 (-5) != 4 || f8 (0) != -1)
+ abort ();
+ return 0;
+}
--- gcc/testsuite/gcc.dg/pr68670-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr68670-1.c (revision 231526)
@@ -0,0 +1,5 @@
+/* PR rtl-optimization/68670 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ftracer" } */
+
+#include "../gcc.c-torture/execute/pr68376-1.c"
--- gcc/testsuite/gcc.dg/pr68670-2.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr68670-2.c (revision 231526)
@@ -0,0 +1,5 @@
+/* PR rtl-optimization/68670 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ftracer" } */
+
+#include "../gcc.c-torture/execute/pr68376-2.c"
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-01-01 Jakub Jelinek <jakub@redhat.com>
PR target/69015
* ifcvt.c (find_cond_trap): Give up if returnjump_p (jump).
* gcc.dg/pr69015.c: New test.
--- gcc/ifcvt.c (revision 232019)
+++ gcc/ifcvt.c (revision 232020)
@@ -4526,8 +4526,11 @@ find_cond_trap (basic_block test_bb, edg
return FALSE;
/* If the conditional jump is more than just a conditional jump, then
- we can not do if-conversion on this block. */
- if (! onlyjump_p (jump))
+ we can not do if-conversion on this block. Give up for returnjump_p,
+ changing a conditional return followed by unconditional trap for
+ conditional trap followed by unconditional return is likely not
+ beneficial and harder to handle. */
+ if (! onlyjump_p (jump) || returnjump_p (jump))
return FALSE;
/* We must be comparing objects whose modes imply the size. */
--- gcc/testsuite/gcc.dg/pr69015.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr69015.c (revision 232020)
@@ -0,0 +1,10 @@
+/* PR target/69015 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-if-conversion" } */
+
+void
+foo (int c)
+{
+ if (c)
+ __builtin_trap ();
+}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-01-07 Jakub Jelinek <jakub@redhat.com>
PR middle-end/68960
* gimple-expr.c (copy_var_decl): If var has DECL_USER_ALIGN set, copy
it and DECL_ALIGN too.
* testsuite/libgomp.c/pr68960.c: New test.
--- gcc/gimple-expr.c (revision 232121)
+++ gcc/gimple-expr.c (revision 232122)
@@ -375,6 +375,11 @@ copy_var_decl (tree var, tree name, tree
TREE_USED (copy) = 1;
DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var);
+ if (DECL_USER_ALIGN (var))
+ {
+ DECL_ALIGN (copy) = DECL_ALIGN (var);
+ DECL_USER_ALIGN (copy) = 1;
+ }
return copy;
}
--- libgomp/testsuite/libgomp.c/pr68960.c (revision 0)
+++ libgomp/testsuite/libgomp.c/pr68960.c (revision 232122)
@@ -0,0 +1,25 @@
+/* PR middle-end/68960 */
+/* { dg-do run } */
+
+int
+main ()
+{
+ int temp[257] __attribute__ ((aligned (256))) = { 0 };
+ #pragma omp parallel private (temp) num_threads (2)
+ {
+ int *p = &temp[0];
+ asm volatile ("" : "+g" (p));
+ if (((__UINTPTR_TYPE__) p) & 255)
+ __builtin_abort ();
+ }
+ #pragma omp parallel num_threads (2)
+ #pragma omp single
+ #pragma omp task firstprivate (temp)
+ {
+ int *p = &temp[0];
+ asm volatile ("" : "+g" (p));
+ if (((__UINTPTR_TYPE__) p) & 255)
+ __builtin_abort ();
+ }
+ return 0;
+}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-01-08 Jakub Jelinek <jakub@redhat.com>
PR fortran/69128
* trans.h (OMPWS_SCALARIZER_BODY): Define.
(OMPWS_NOWAIT): Renumber.
* trans-stmt.c (gfc_trans_where_3): Only set OMPWS_SCALARIZER_WS
if OMPWS_SCALARIZER_BODY is not set already, and set also
OMPWS_SCALARIZER_BODY until the final loop creation.
* trans-expr.c (gfc_trans_assignment_1): Likewise.
* trans-openmp.c (gfc_trans_omp_workshare): Also clear
OMPWS_SCALARIZER_BODY.
* trans-array.c (gfc_trans_scalarized_loop_end): Don't create
OMP_FOR if OMPWS_SCALARIZER_BODY is set.
* gfortran.dg/gomp/pr69128.f90: New test.
--- gcc/fortran/trans.h (revision 232150)
+++ gcc/fortran/trans.h (revision 232151)
@@ -1039,7 +1039,9 @@ extern const char gfc_msg_wrong_return[]
construct is not workshared. */
#define OMPWS_SCALARIZER_WS 4 /* Set if scalarizer should attempt
to create parallel loops. */
-#define OMPWS_NOWAIT 8 /* Use NOWAIT on OMP_FOR. */
+#define OMPWS_SCALARIZER_BODY 8 /* Set if handling body of potential
+ parallel loop. */
+#define OMPWS_NOWAIT 16 /* Use NOWAIT on OMP_FOR. */
extern int ompws_flags;
#endif /* GFC_TRANS_H */
--- gcc/fortran/trans-stmt.c (revision 232150)
+++ gcc/fortran/trans-stmt.c (revision 232151)
@@ -5057,10 +5057,15 @@ gfc_trans_where_3 (gfc_code * cblock, gf
gfc_loopinfo loop;
gfc_ss *edss = 0;
gfc_ss *esss = 0;
+ bool maybe_workshare = false;
/* Allow the scalarizer to workshare simple where loops. */
- if (ompws_flags & OMPWS_WORKSHARE_FLAG)
- ompws_flags |= OMPWS_SCALARIZER_WS;
+ if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
+ == OMPWS_WORKSHARE_FLAG)
+ {
+ maybe_workshare = true;
+ ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
+ }
cond = cblock->expr1;
tdst = cblock->next->expr1;
@@ -5160,6 +5165,8 @@ gfc_trans_where_3 (gfc_code * cblock, gf
gfc_add_expr_to_block (&body, tmp);
gfc_add_block_to_block (&body, &cse.post);
+ if (maybe_workshare)
+ ompws_flags &= ~OMPWS_SCALARIZER_BODY;
gfc_trans_scalarizing_loops (&loop, &body);
gfc_add_block_to_block (&block, &loop.pre);
gfc_add_block_to_block (&block, &loop.post);
--- gcc/fortran/trans-expr.c (revision 232150)
+++ gcc/fortran/trans-expr.c (revision 232151)
@@ -9160,6 +9160,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1
bool scalar_to_array;
tree string_length;
int n;
+ bool maybe_workshare = false;
/* Assignment of the form lhs = rhs. */
gfc_start_block (&block);
@@ -9234,8 +9235,13 @@ gfc_trans_assignment_1 (gfc_expr * expr1
}
/* Allow the scalarizer to workshare array assignments. */
- if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
- ompws_flags |= OMPWS_SCALARIZER_WS;
+ if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
+ == OMPWS_WORKSHARE_FLAG
+ && loop.temp_ss == NULL)
+ {
+ maybe_workshare = true;
+ ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
+ }
/* Start the scalarized loop body. */
gfc_start_scalarized_body (&loop, &body);
@@ -9384,6 +9390,9 @@ gfc_trans_assignment_1 (gfc_expr * expr1
gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
}
+ if (maybe_workshare)
+ ompws_flags &= ~OMPWS_SCALARIZER_BODY;
+
/* Generate the copying loops. */
gfc_trans_scalarizing_loops (&loop, &body);
--- gcc/fortran/trans-openmp.c (revision 232150)
+++ gcc/fortran/trans-openmp.c (revision 232151)
@@ -4297,7 +4297,7 @@ gfc_trans_omp_workshare (gfc_code *code,
/* By default, every gfc_code is a single unit of work. */
ompws_flags |= OMPWS_CURR_SINGLEUNIT;
- ompws_flags &= ~OMPWS_SCALARIZER_WS;
+ ompws_flags &= ~(OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY);
switch (code->op)
{
--- gcc/fortran/trans-array.c (revision 232150)
+++ gcc/fortran/trans-array.c (revision 232151)
@@ -3601,7 +3601,8 @@ gfc_trans_scalarized_loop_end (gfc_loopi
tree init;
tree incr;
- if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS))
+ if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS
+ | OMPWS_SCALARIZER_BODY))
== (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
&& n == loop->dimen - 1)
{
--- gcc/testsuite/gfortran.dg/gomp/pr69128.f90 (revision 0)
+++ gcc/testsuite/gfortran.dg/gomp/pr69128.f90 (revision 232151)
@@ -0,0 +1,23 @@
+! PR fortran/69128
+! { dg-do compile }
+
+program test
+ implicit none
+ interface
+ subroutine use(b, c)
+ real, allocatable :: b(:), c(:)
+ end subroutine
+ end interface
+ real, allocatable :: a(:,:), b(:), c(:)
+ integer :: dim1, dim2, i,j
+ dim1=10000
+ dim2=500
+ allocate(a(dim1,dim2),b(dim1),c(dim1))
+ call random_number(a)
+
+!$omp parallel workshare
+ b(:) = maxval(a(:,:), dim=2)
+ c(:) = sum(a(:,:), dim=2)
+!$omp end parallel workshare
+ call use(b, c)
+end program
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-01-11 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/69214
* tree-vrp.c (simplify_cond_using_ranges): Don't propagate
innerop into a comparison if SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
Formatting fix.
* gcc.c-torture/compile/pr69214.c: New test.
--- gcc/tree-vrp.c (revision 232234)
+++ gcc/tree-vrp.c (revision 232235)
@@ -9534,7 +9534,8 @@ simplify_cond_using_ranges (gcond *stmt)
innerop = gimple_assign_rhs1 (def_stmt);
if (TREE_CODE (innerop) == SSA_NAME
- && !POINTER_TYPE_P (TREE_TYPE (innerop)))
+ && !POINTER_TYPE_P (TREE_TYPE (innerop))
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
{
value_range_t *vr = get_value_range (innerop);
@@ -9565,8 +9566,8 @@ simplify_cond_using_ranges (gcond *stmt)
else
location = gimple_location (stmt);
warning_at (location, OPT_Wstrict_overflow,
- "assuming signed overflow does not occur when "
- "simplifying conditional");
+ "assuming signed overflow does not occur when "
+ "simplifying conditional");
}
tree newconst = fold_convert (TREE_TYPE (innerop), op1);
--- gcc/testsuite/gcc.c-torture/compile/pr69214.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr69214.c (revision 232235)
@@ -0,0 +1,17 @@
+/* PR tree-optimization/69214 */
+
+extern void bar (void);
+extern int __setjmp (char *);
+
+void
+foo (char *p)
+{
+ int d = 0;
+ bar ();
+ if (__setjmp (p))
+ return;
+ long a = d;
+ d = 8;
+ if (!a)
+ bar ();
+}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-01-19 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/68955
PR rtl-optimization/64557
* dse.c (record_store, check_mem_read_rtx): Don't call get_addr
here. Fix up formatting.
* alias.c (get_addr): Handle VALUE +/- CONST_SCALAR_INT_P.
* gcc.dg/torture/pr68955.c: New test.
--- gcc/dse.c (revision 232553)
+++ gcc/dse.c (revision 232554)
@@ -1571,14 +1571,9 @@ record_store (rtx body, bb_info_t bb_inf
mem_addr = base->val_rtx;
else
{
- group_info_t group
- = rtx_group_vec[group_id];
+ group_info_t group = rtx_group_vec[group_id];
mem_addr = group->canon_base_addr;
}
- /* get_addr can only handle VALUE but cannot handle expr like:
- VALUE + OFFSET, so call get_addr to get original addr for
- mem_addr before plus_constant. */
- mem_addr = get_addr (mem_addr);
if (offset)
mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
}
@@ -2188,14 +2183,9 @@ check_mem_read_rtx (rtx *loc, bb_info_t
mem_addr = base->val_rtx;
else
{
- group_info_t group
- = rtx_group_vec[group_id];
+ group_info_t group = rtx_group_vec[group_id];
mem_addr = group->canon_base_addr;
}
- /* get_addr can only handle VALUE but cannot handle expr like:
- VALUE + OFFSET, so call get_addr to get original addr for
- mem_addr before plus_constant. */
- mem_addr = get_addr (mem_addr);
if (offset)
mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
}
--- gcc/alias.c (revision 232553)
+++ gcc/alias.c (revision 232554)
@@ -2193,8 +2193,8 @@ refs_newer_value_p (const_rtx expr, rtx
}
/* Convert the address X into something we can use. This is done by returning
- it unchanged unless it is a value; in the latter case we call cselib to get
- a more useful rtx. */
+ it unchanged unless it is a VALUE or VALUE +/- constant; for VALUE
+ we call cselib to get a more useful rtx. */
rtx
get_addr (rtx x)
@@ -2203,7 +2203,23 @@ get_addr (rtx x)
struct elt_loc_list *l;
if (GET_CODE (x) != VALUE)
- return x;
+ {
+ if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS)
+ && GET_CODE (XEXP (x, 0)) == VALUE
+ && CONST_SCALAR_INT_P (XEXP (x, 1)))
+ {
+ rtx op0 = get_addr (XEXP (x, 0));
+ if (op0 != XEXP (x, 0))
+ {
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ return plus_constant (GET_MODE (x), op0, INTVAL (XEXP (x, 1)));
+ return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
+ op0, XEXP (x, 1));
+ }
+ }
+ return x;
+ }
v = CSELIB_VAL_PTR (x);
if (v)
{
--- gcc/testsuite/gcc.dg/torture/pr68955.c (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr68955.c (revision 232554)
@@ -0,0 +1,41 @@
+/* PR rtl-optimization/68955 */
+/* { dg-do run } */
+/* { dg-output "ONE1ONE" } */
+
+int a, b, c, d, g, m;
+int i[7][7][5] = { { { 5 } }, { { 5 } },
+ { { 5 }, { 5 }, { 5 }, { 5 }, { 5 }, { -1 } } };
+static int j = 11;
+short e, f, h, k, l;
+
+static void
+foo ()
+{
+ for (; e < 5; e++)
+ for (h = 3; h; h--)
+ {
+ for (g = 1; g < 6; g++)
+ {
+ m = c == 0 ? b : b / c;
+ i[e][1][e] = i[1][1][1] | (m & l) && f;
+ }
+ for (k = 0; k < 6; k++)
+ {
+ for (d = 0; d < 6; d++)
+ i[1][e][h] = i[h][k][e] >= l;
+ i[e + 2][h + 3][e] = 6 & l;
+ i[2][1][2] = a;
+ for (; j < 5;)
+ for (;;)
+ ;
+ }
+ }
+}
+
+int
+main ()
+{
+ foo ();
+ __builtin_printf ("ONE%dONE\n", i[1][0][2]);
+ return 0;
+}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-01-21 Jakub Jelinek <jakub@redhat.com>
PR middle-end/67653
* gimplify.c (gimplify_asm_expr): Warn if it is too late to
attempt to mark memory input operand addressable and
call prepare_gimple_addressable in that case. Don't adjust
input_location for diagnostics, use error_at instead.
* c-c++-common/pr67653.c: New test.
* gcc.dg/torture/pr29119.c: Add dg-warning.
--- gcc/gimplify.c (revision 232639)
+++ gcc/gimplify.c (revision 232640)
@@ -5305,12 +5305,38 @@ gimplify_asm_expr (tree *expr_p, gimple_
TREE_VALUE (link) = error_mark_node;
tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
is_gimple_lvalue, fb_lvalue | fb_mayfail);
+ if (tret != GS_ERROR)
+ {
+ /* Unlike output operands, memory inputs are not guaranteed
+ to be lvalues by the FE, and while the expressions are
+ marked addressable there, if it is e.g. a statement
+ expression, temporaries in it might not end up being
+ addressable. They might be already used in the IL and thus
+ it is too late to make them addressable now though. */
+ tree x = TREE_VALUE (link);
+ while (handled_component_p (x))
+ x = TREE_OPERAND (x, 0);
+ if (TREE_CODE (x) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
+ x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
+ if ((TREE_CODE (x) == VAR_DECL
+ || TREE_CODE (x) == PARM_DECL
+ || TREE_CODE (x) == RESULT_DECL)
+ && !TREE_ADDRESSABLE (x)
+ && is_gimple_reg (x))
+ {
+ warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
+ input_location), 0,
+ "memory input %d is not directly addressable",
+ i);
+ prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
+ }
+ }
mark_addressable (TREE_VALUE (link));
if (tret == GS_ERROR)
{
- if (EXPR_HAS_LOCATION (TREE_VALUE (link)))
- input_location = EXPR_LOCATION (TREE_VALUE (link));
- error ("memory input %d is not directly addressable", i);
+ error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
+ "memory input %d is not directly addressable", i);
ret = tret;
}
}
--- gcc/testsuite/gcc.dg/torture/pr29119.c (revision 232639)
+++ gcc/testsuite/gcc.dg/torture/pr29119.c (revision 232640)
@@ -2,6 +2,5 @@
void ldt_add_entry(void)
{
- __asm__ ("" :: "m"(({unsigned __v; __v;})));
+ __asm__ ("" :: "m"(({unsigned __v; __v;}))); /* { dg-warning "memory input 0 is not directly addressable" } */
}
-
--- gcc/testsuite/c-c++-common/pr67653.c (revision 0)
+++ gcc/testsuite/c-c++-common/pr67653.c (revision 232640)
@@ -0,0 +1,8 @@
+/* PR middle-end/67653 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+ __asm__ ("" : : "m" (({ static int a; a; }))); /* { dg-warning "memory input 0 is not directly addressable" } */
+}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-01-22 Jakub Jelinek <jakub@redhat.com>
PR target/69432
* config/i386/i386.c (expand_small_movmem_or_setmem,
expand_set_or_movmem_prologue_epilogue_by_misaligned_moves): Spelling
fixes.
(ix86_expand_set_or_movmem): Call do_pending_stack_adjust () early
if dynamic_check != -1.
* g++.dg/opt/pr69432.C: New test.
--- gcc/config/i386/i386.c (revision 232753)
+++ gcc/config/i386/i386.c (revision 232754)
@@ -24376,7 +24377,7 @@ expand_small_movmem_or_setmem (rtx destm
if (DYNAMIC_CHECK)
Round COUNT down to multiple of SIZE
<< optional caller supplied zero size guard is here >>
- << optional caller suppplied dynamic check is here >>
+ << optional caller supplied dynamic check is here >>
<< caller supplied main copy loop is here >>
}
done_label:
@@ -24550,8 +24551,8 @@ expand_set_or_movmem_prologue_epilogue_b
else
*min_size = 0;
- /* Our loops always round down the bock size, but for dispatch to library
- we need precise value. */
+ /* Our loops always round down the block size, but for dispatch to
+ library we need precise value. */
if (dynamic_check)
*count = expand_simple_binop (GET_MODE (*count), AND, *count,
GEN_INT (-size), *count, 1, OPTAB_DIRECT);
@@ -25129,6 +25130,13 @@ ix86_expand_set_or_movmem (rtx dst, rtx
size_needed = GET_MODE_SIZE (move_mode) * unroll_factor;
epilogue_size_needed = size_needed;
+ /* If we are going to call any library calls conditionally, make sure any
+ pending stack adjustment happen before the first conditional branch,
+ otherwise they will be emitted before the library call only and won't
+ happen from the other branches. */
+ if (dynamic_check != -1)
+ do_pending_stack_adjust ();
+
desired_align = decide_alignment (align, alg, expected_size, move_mode);
if (!TARGET_ALIGN_STRINGOPS || noalign)
align = desired_align;
--- gcc/testsuite/g++.dg/opt/pr69432.C (revision 0)
+++ gcc/testsuite/g++.dg/opt/pr69432.C (revision 232754)
@@ -0,0 +1,62 @@
+// PR target/69432
+// { dg-do compile }
+// { dg-options "-O3" }
+// { dg-additional-options "-minline-stringops-dynamically" { target i?86-*-* x86_64-*-* } }
+
+template <typename S, typename T, typename U>
+void
+f1 (S x, T y, U z)
+{
+ for (; y; --y, ++x)
+ *x = z;
+}
+
+template <typename S, typename T, typename U>
+void f2 (S x, T y, U z)
+{
+ f1 (x, y, z);
+}
+
+struct A {};
+struct B { static char f3 (A, unsigned); };
+
+template <typename S, typename U>
+void f4 (S, U);
+
+struct C
+{
+ template <typename S, typename T, typename U>
+ static S f5 (S x, T y, U z) { f2 (x, y, z); }
+};
+
+template <typename S, typename T, typename U>
+void f6 (S x, T y, U z) { C::f5 (x, y, z); }
+
+template <typename S, typename T, typename U, typename V>
+void f7 (S x, T y, U z, V) { f6 (x, y, z); }
+
+struct E
+{
+ struct D : A { char e; D (A); };
+ A f;
+ E (int x) : g(f) { f8 (x); }
+ ~E ();
+ D g;
+ void f9 (int x) { x ? B::f3 (g, x) : char (); }
+ void f8 (int x) { f9 (x); }
+};
+
+struct F : E
+{
+ F (int x) : E(x) { f10 (x); f4 (this, 0); }
+ char h;
+ void f10 (int x) { f7 (&g.e, x, h, 0); }
+};
+
+long a;
+
+void
+test ()
+{
+ F b(a);
+}
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-01-28 Jakub Jelinek <jakub@redhat.com>
PR pch/68176
* files.c (_cpp_find_file): Set file->implicit_preinclude even if
included from file->implicit_preinclude header.
--- libcpp/files.c (revision 232955)
+++ libcpp/files.c (revision 232956)
@@ -522,7 +522,10 @@ _cpp_find_file (cpp_reader *pfile, const
return entry->u.file;
file = make_cpp_file (pfile, start_dir, fname);
- file->implicit_preinclude = implicit_preinclude;
+ file->implicit_preinclude
+ = (implicit_preinclude
+ || (pfile->buffer
+ && pfile->buffer->file->implicit_preinclude));
/* Try each path in the include chain. */
for (; !fake ;)
-------------- next part --------------
2016-02-11 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2016-02-08 Jakub Jelinek <jakub@redhat.com>
PR c++/59627
* parser.c (cp_parser_omp_declare_reduction): Set assembler name
of the DECL_OMP_DECLARE_REDUCTION_P decls.
* g++.dg/gomp/pr59627.C: New test.
--- gcc/cp/parser.c (revision 233224)
+++ gcc/cp/parser.c (revision 233225)
@@ -36080,6 +36080,7 @@ cp_parser_omp_declare_reduction (cp_pars
DECL_DECLARED_INLINE_P (fndecl) = 1;
DECL_IGNORED_P (fndecl) = 1;
DECL_OMP_DECLARE_REDUCTION_P (fndecl) = 1;
+ SET_DECL_ASSEMBLER_NAME (fndecl, get_identifier ("<udr>"));
DECL_ATTRIBUTES (fndecl)
= tree_cons (get_identifier ("gnu_inline"), NULL_TREE,
DECL_ATTRIBUTES (fndecl));
--- gcc/testsuite/g++.dg/gomp/pr59627.C (revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr59627.C (revision 233225)
@@ -0,0 +1,14 @@
+// PR c++/59627
+// { dg-do compile { target lto } }
+// { dg-options "-fopenmp -flto" }
+
+struct A { A () : i (0) {} int i; };
+
+void
+foo ()
+{
+ A a;
+ #pragma omp declare reduction (+: A: omp_out.i += omp_in.i)
+ #pragma omp parallel reduction (+: a)
+ ;
+}
More information about the Gcc-patches
mailing list