From: Richard Biener Date: Wed, 10 Jun 2015 12:53:09 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-4.8.5~77 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78fe7c42fc2b2ba8d2da0e776e2eec96a63dcca5;p=thirdparty%2Fgcc.git backport: [multiple changes] 2015-06-10 Richard Biener Backport from mainline 2014-04-04 Cong Hou PR tree-optimization/60656 * tree-vect-stmts.c (supportable_widening_operation): Fix a bug that elements in a vector with vect_used_by_reduction property are incorrectly reordered when the operation on it is not consistant with the one in reduction operation. * gcc.dg/vect/pr60656.c: New test. 2014-01-31 Richard Biener PR middle-end/59990 * builtins.c (fold_builtin_memory_op): Make sure to not use a floating-point mode or a boolean or enumeral type for the copy operation. * gcc.dg/torture/pr59990.c: New testcase. * gcc.target/i386/pr49168-1.c: Adjust. From-SVN: r224327 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 80c4ee859c0d..885e9c70cfaa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2015-06-10 Richard Biener + + Backport from mainline + 2014-04-04 Cong Hou + + PR tree-optimization/60656 + * tree-vect-stmts.c (supportable_widening_operation): + Fix a bug that elements in a vector with vect_used_by_reduction + property are incorrectly reordered when the operation on it is not + consistant with the one in reduction operation. + + 2014-01-31 Richard Biener + + PR middle-end/59990 + * builtins.c (fold_builtin_memory_op): Make sure to not + use a floating-point mode or a boolean or enumeral type for + the copy operation. + 2015-06-10 Jakub Jelinek PR target/66470 diff --git a/gcc/builtins.c b/gcc/builtins.c index bb6c664394bc..c3c3ce37d39a 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8911,6 +8911,12 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, if (!POINTER_TYPE_P (TREE_TYPE (src)) || !POINTER_TYPE_P (TREE_TYPE (dest))) return NULL_TREE; + /* In the following try to find a type that is most natural to be + used for the memcpy source and destination and that allows + the most optimization when memcpy is turned into a plain assignment + using that type. In theory we could always use a char[len] type + but that only gains us that the destination and source possibly + no longer will have their address taken. */ /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */ if (TREE_CODE (src) == POINTER_PLUS_EXPR) { @@ -8946,6 +8952,41 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, || TREE_ADDRESSABLE (desttype)) return NULL_TREE; + /* Make sure we are not copying using a floating-point mode or + a type whose size possibly does not match its precision. */ + if (FLOAT_MODE_P (TYPE_MODE (desttype)) + || TREE_CODE (desttype) == BOOLEAN_TYPE + || TREE_CODE (desttype) == ENUMERAL_TYPE) + { + /* A more suitable int_mode_for_mode would return a vector + integer mode for a vector float mode or a integer complex + mode for a float complex mode if there isn't a regular + integer mode covering the mode of desttype. */ + enum machine_mode mode = int_mode_for_mode (TYPE_MODE (desttype)); + if (mode == BLKmode) + desttype = NULL_TREE; + else + desttype = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), + 1); + } + if (FLOAT_MODE_P (TYPE_MODE (srctype)) + || TREE_CODE (srctype) == BOOLEAN_TYPE + || TREE_CODE (srctype) == ENUMERAL_TYPE) + { + enum machine_mode mode = int_mode_for_mode (TYPE_MODE (srctype)); + if (mode == BLKmode) + srctype = NULL_TREE; + else + srctype = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), + 1); + } + if (!srctype) + srctype = desttype; + if (!desttype) + desttype = srctype; + if (!srctype) + return NULL_TREE; + src_align = get_pointer_alignment (src); dest_align = get_pointer_alignment (dest); if (dest_align < TYPE_ALIGN (desttype) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9bda3339c2e2..a66ec2ec0bdc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2015-06-10 Richard Biener + + Backport from mainline + 2014-04-04 Cong Hou + + PR tree-optimization/60656 + * gcc.dg/vect/pr60656.c: New test. + + 2014-01-31 Richard Biener + + PR middle-end/59990 + * gcc.dg/torture/pr59990.c: New testcase. + * gcc.target/i386/pr49168-1.c: Adjust. + 2015-06-10 Jakub Jelinek PR target/66470 diff --git a/gcc/testsuite/gcc.dg/torture/pr59990.c b/gcc/testsuite/gcc.dg/torture/pr59990.c new file mode 100644 index 000000000000..e54f9b7efb06 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr59990.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ + +extern void abort (void); + +unsigned char value[4] = { 66, 9, 160, 255 }; + +int main (void) +{ + volatile float f; + unsigned char a[4]; + + __builtin_memcpy ((void *)&f, value, 4); + __builtin_memcpy (a, (void *)&f, 4); + if (a[2] != 160) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr60656.c b/gcc/testsuite/gcc.dg/vect/pr60656.c new file mode 100644 index 000000000000..a787f0406727 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr60656.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_long } */ + +#include "tree-vect.h" + +__attribute__ ((noinline)) long +foo () +{ + int v[] = {5000, 5001, 5002, 5003}; + long s = 0; + int i; + + for(i = 0; i < 4; ++i) + { + long P = v[i]; + s += P * P * P; + } + return s; +} + +long +bar () +{ + int v[] = {5000, 5001, 5002, 5003}; + long s = 0; + int i; + + for(i = 0; i < 4; ++i) + { + long P = v[i]; + s += P * P * P; + __asm__ volatile (""); + } + return s; +} + +int main() +{ + check_vect (); + + if (foo () != bar ()) + abort (); + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr49168-1.c b/gcc/testsuite/gcc.target/i386/pr49168-1.c index 9676dc85a8ef..f8cce4a8ac97 100644 --- a/gcc/testsuite/gcc.target/i386/pr49168-1.c +++ b/gcc/testsuite/gcc.target/i386/pr49168-1.c @@ -2,7 +2,7 @@ /* { dg-do compile } */ /* { dg-options "-O2 -msse2 -mtune=generic" } */ /* { dg-final { scan-assembler-not "movdqa\[\t \]*%xmm\[0-9\]\+,\[^,\]*" } } */ -/* { dg-final { scan-assembler "movdqu\[\t \]*%xmm\[0-9\]\+,\[^,\]*" } } */ +/* { dg-final { scan-assembler "mov\[dlh\]\[qp\]\[us\]\[\t \]*%xmm\[0-9\]\+,\[^,\]*" } } */ void flt128_va (void *mem, __float128 d) diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 2301ce89f329..53c286c95085 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -6459,7 +6459,21 @@ supportable_widening_operation (enum tree_code code, gimple stmt, stmt, vectype_out, vectype_in, code1, code2, multi_step_cvt, interm_types)) - return true; + { + /* Elements in a vector with vect_used_by_reduction property cannot + be reordered if the use chain with this property does not have the + same operation. One such an example is s += a * b, where elements + in a and b cannot be reordered. Here we check if the vector defined + by STMT is only directly used in the reduction statement. */ + tree lhs = gimple_assign_lhs (stmt); + use_operand_p dummy; + gimple use_stmt; + stmt_vec_info use_stmt_info = NULL; + if (single_imm_use (lhs, &dummy, &use_stmt) + && (use_stmt_info = vinfo_for_stmt (use_stmt)) + && STMT_VINFO_DEF_TYPE (use_stmt_info) == vect_reduction_def) + return true; + } c1 = VEC_WIDEN_MULT_LO_EXPR; c2 = VEC_WIDEN_MULT_HI_EXPR; break;