+2015-06-10 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2014-04-04 Cong Hou <congh@google.com>
+
+ 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 <rguenther@suse.de>
+
+ 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 <jakub@redhat.com>
PR target/66470
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)
{
|| 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)
+2015-06-10 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2014-04-04 Cong Hou <congh@google.com>
+
+ PR tree-optimization/60656
+ * gcc.dg/vect/pr60656.c: New test.
+
+ 2014-01-31 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59990
+ * gcc.dg/torture/pr59990.c: New testcase.
+ * gcc.target/i386/pr49168-1.c: Adjust.
+
2015-06-10 Jakub Jelinek <jakub@redhat.com>
PR target/66470
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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" } } */
/* { 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)
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;