aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-07-28 11:27:45 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-07-28 11:27:45 +0000
commit92e29a5e86c8adc88ee17a483d7284d7bb9e090c (patch)
tree7c89972072bd6357aef834097b5e62e1378d814d /gcc
parentc9b39a4955f56fe609ef54784f7bf48c4cba6b1a (diff)
downloadgcc-92e29a5e86c8adc88ee17a483d7284d7bb9e090c.zip
gcc-92e29a5e86c8adc88ee17a483d7284d7bb9e090c.tar.gz
gcc-92e29a5e86c8adc88ee17a483d7284d7bb9e090c.tar.bz2
re PR middle-end/81502 (In some cases the data is moved to memory unnecessarily [partial regression])
2017-07-28 Richard Biener <rguenther@suse.de> PR tree-optimization/81502 * match.pd: Add pattern combining BIT_INSERT_EXPR with BIT_FIELD_REF. * tree-cfg.c (verify_expr): Verify types of BIT_FIELD_REF size/pos operands. (verify_gimple_assign_ternary): Likewise for BIT_INSERT_EXPR pos. * gimple-fold.c (maybe_canonicalize_mem_ref_addr): Use bitsizetype for BIT_FIELD_REF args. * fold-const.c (make_bit_field_ref): Likewise. * tree-vect-stmts.c (vectorizable_simd_clone_call): Likewise. * gcc.target/i386/pr81502.c: New testcase. From-SVN: r250659
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/fold-const.c2
-rw-r--r--gcc/gimple-fold.c2
-rw-r--r--gcc/match.pd22
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr81502.c34
-rw-r--r--gcc/tree-cfg.c5
-rw-r--r--gcc/tree-vect-stmts.c4
8 files changed, 82 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61d389e..964fa1c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2017-07-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/81502
+ * match.pd: Add pattern combining BIT_INSERT_EXPR with
+ BIT_FIELD_REF.
+ * tree-cfg.c (verify_expr): Verify types of BIT_FIELD_REF
+ size/pos operands.
+ (verify_gimple_assign_ternary): Likewise for BIT_INSERT_EXPR pos.
+ * gimple-fold.c (maybe_canonicalize_mem_ref_addr): Use bitsizetype
+ for BIT_FIELD_REF args.
+ * fold-const.c (make_bit_field_ref): Likewise.
+ * tree-vect-stmts.c (vectorizable_simd_clone_call): Likewise.
+
2017-07-28 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/80998
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index d40b9aa..ae94659 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3936,7 +3936,7 @@ make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type,
bftype = build_nonstandard_integer_type (bitsize, 0);
result = build3_loc (loc, BIT_FIELD_REF, bftype, inner,
- size_int (bitsize), bitsize_int (bitpos));
+ bitsize_int (bitsize), bitsize_int (bitpos));
REF_REVERSE_STORAGE_ORDER (result) = reversep;
if (bftype != type)
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index d94dc9c..d82d060 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -4245,7 +4245,7 @@ maybe_canonicalize_mem_ref_addr (tree *t)
TREE_TYPE (*t),
TREE_OPERAND (TREE_OPERAND (*t, 0), 0),
TYPE_SIZE (TREE_TYPE (*t)),
- wide_int_to_tree (sizetype, idx));
+ wide_int_to_tree (bitsizetype, idx));
res = true;
}
}
diff --git a/gcc/match.pd b/gcc/match.pd
index 732b80c..60f262d 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4178,3 +4178,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ CONSTRUCTOR_ELT (ctor, idx / k)->value; })
(BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / k)->value; }
@1 { bitsize_int ((idx % k) * width); })))))))))
+
+/* Simplify a bit extraction from a bit insertion for the cases with
+ the inserted element fully covering the extraction or the insertion
+ not touching the extraction. */
+(simplify
+ (BIT_FIELD_REF (bit_insert @0 @1 @ipos) @rsize @rpos)
+ (with
+ {
+ unsigned HOST_WIDE_INT isize;
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ isize = TYPE_PRECISION (TREE_TYPE (@1));
+ else
+ isize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (@1)));
+ }
+ (switch
+ (if (wi::leu_p (@ipos, @rpos)
+ && wi::leu_p (wi::add (@rpos, @rsize), wi::add (@ipos, isize)))
+ (BIT_FIELD_REF @1 @rsize { wide_int_to_tree (bitsizetype,
+ wi::sub (@rpos, @ipos)); }))
+ (if (wi::geu_p (@ipos, wi::add (@rpos, @rsize))
+ || wi::geu_p (@rpos, wi::add (@ipos, isize)))
+ (BIT_FIELD_REF @0 @rsize @rpos)))))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5c41f43..396f0b1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-07-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/81502
+ * gcc.target/i386/pr81502.c: New testcase.
+
2017-07-28 Martin Liska <mliska@suse.cz>
PR sanitizer/81460
diff --git a/gcc/testsuite/gcc.target/i386/pr81502.c b/gcc/testsuite/gcc.target/i386/pr81502.c
new file mode 100644
index 0000000..d28791a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr81502.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -msse2" } */
+
+#include <emmintrin.h>
+
+#define SIZE (sizeof (void *))
+
+static int foo(unsigned char (*foo)[SIZE])
+{
+ __m128i acc = _mm_set_epi32(0, 0, 0, 0);
+ size_t i = 0;
+ for(; i + sizeof(__m128i) <= SIZE; i += sizeof(__m128i)) {
+ __m128i word;
+ __builtin_memcpy(&word, foo + i, sizeof(__m128i));
+ acc = _mm_add_epi32(word, acc);
+ }
+ if (i != SIZE) {
+ __m128i word = _mm_set_epi32(0, 0, 0, 0);
+ __builtin_memcpy(&word, foo + i, SIZE - i); // (1)
+ acc = _mm_add_epi32(word, acc);
+ }
+ int res;
+ __builtin_memcpy(&res, &acc, sizeof(res));
+ return res;
+}
+
+int bar(void *ptr)
+{
+ unsigned char buf[SIZE];
+ __builtin_memcpy(buf, &ptr, SIZE);
+ return foo((unsigned char(*)[SIZE])buf);
+}
+
+/* { dg-final { scan-assembler-times "mov" 1 } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index f664ffe..733c92f 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3054,7 +3054,9 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
tree t1 = TREE_OPERAND (t, 1);
tree t2 = TREE_OPERAND (t, 2);
if (!tree_fits_uhwi_p (t1)
- || !tree_fits_uhwi_p (t2))
+ || !tree_fits_uhwi_p (t2)
+ || !types_compatible_p (bitsizetype, TREE_TYPE (t1))
+ || !types_compatible_p (bitsizetype, TREE_TYPE (t2)))
{
error ("invalid position or size operand to BIT_FIELD_REF");
return t;
@@ -4248,6 +4250,7 @@ verify_gimple_assign_ternary (gassign *stmt)
return true;
}
if (! tree_fits_uhwi_p (rhs3)
+ || ! types_compatible_p (bitsizetype, TREE_TYPE (rhs3))
|| ! tree_fits_uhwi_p (TYPE_SIZE (rhs2_type)))
{
error ("invalid position or size in BIT_INSERT_EXPR");
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 8a63104..18dd1a4 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -3531,7 +3531,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
arginfo[i].op = vec_oprnd0;
vec_oprnd0
= build3 (BIT_FIELD_REF, atype, vec_oprnd0,
- size_int (prec),
+ bitsize_int (prec),
bitsize_int ((m & (k - 1)) * prec));
new_stmt
= gimple_build_assign (make_ssa_name (atype),
@@ -3692,7 +3692,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
}
else
t = build3 (BIT_FIELD_REF, vectype, new_temp,
- size_int (prec), bitsize_int (l * prec));
+ bitsize_int (prec), bitsize_int (l * prec));
new_stmt
= gimple_build_assign (make_ssa_name (vectype), t);
vect_finish_stmt_generation (stmt, new_stmt, gsi);