aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-07-13 13:01:06 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-07-13 13:01:06 +0000
commita8ab21e5e6bd37732a16f1764d2ab723e9ddd104 (patch)
treee9e2cb5a1464a5ffa41a29537b01eba96cc0b689
parente8f808b30e83bb6bfa8ff0984fb13b136b3bd4a1 (diff)
downloadgcc-a8ab21e5e6bd37732a16f1764d2ab723e9ddd104.zip
gcc-a8ab21e5e6bd37732a16f1764d2ab723e9ddd104.tar.gz
gcc-a8ab21e5e6bd37732a16f1764d2ab723e9ddd104.tar.bz2
re PR target/53907 (gcc uses unaligned load when aligned load was requested)
2012-07-13 Richard Guenther <rguenther@suse.de> PR tree-optimization/53907 * tree-ssa-forwprop.c (associate_pointerplus): New function. (ssa_forward_propagate_and_combine): Call it. * gcc.target/i386/pr53907.c: New testcase. From-SVN: r189462
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53907.c14
-rw-r--r--gcc/tree-ssa-forwprop.c55
4 files changed, 80 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f7b303a..74dac1c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2012-07-13 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/53907
+ * tree-ssa-forwprop.c (associate_pointerplus): New function.
+ (ssa_forward_propagate_and_combine): Call it.
+
+2012-07-13 Richard Guenther <rguenther@suse.de>
+
PR tree-optimization/53922
* tree-vrp.c (value_inside_range): Change prototype to take
min/max instead of value-range.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c628663..9e6e3b4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2012-07-13 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/53907
+ * gcc.target/i386/pr53907.c: New testcase.
+
+2012-07-13 Richard Guenther <rguenther@suse.de>
+
PR tree-optimization/53922
* gcc.dg/torture/pr53922.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/i386/pr53907.c b/gcc/testsuite/gcc.target/i386/pr53907.c
new file mode 100644
index 0000000..8de8f0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53907.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -msse2" } */
+
+#include <emmintrin.h>
+
+__m128i x(char *s)
+{
+ __m128i sz,z,mvec;
+ s-=((unsigned long) s)%16;
+ sz=_mm_load_si128((__m128i *)s);
+ return sz;
+}
+
+/* { dg-final { scan-assembler "movdqa" } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 3c01623..60d5377 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2474,6 +2474,59 @@ out:
return false;
}
+/* Associate operands of a POINTER_PLUS_EXPR assignmen at *GSI. Returns
+ true if anything changed, false otherwise. */
+
+static bool
+associate_pointerplus (gimple_stmt_iterator *gsi)
+{
+ gimple stmt = gsi_stmt (*gsi);
+ gimple def_stmt;
+ tree ptr, rhs, algn;
+
+ /* Pattern match
+ tem = (sizetype) ptr;
+ tem = tem & algn;
+ tem = -tem;
+ ... = ptr p+ tem;
+ and produce the simpler and easier to analyze with respect to alignment
+ ... = ptr & ~algn; */
+ ptr = gimple_assign_rhs1 (stmt);
+ rhs = gimple_assign_rhs2 (stmt);
+ if (TREE_CODE (rhs) != SSA_NAME)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (rhs);
+ if (!is_gimple_assign (def_stmt)
+ || gimple_assign_rhs_code (def_stmt) != NEGATE_EXPR)
+ return false;
+ rhs = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (rhs) != SSA_NAME)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (rhs);
+ if (!is_gimple_assign (def_stmt)
+ || gimple_assign_rhs_code (def_stmt) != BIT_AND_EXPR)
+ return false;
+ rhs = gimple_assign_rhs1 (def_stmt);
+ algn = gimple_assign_rhs2 (def_stmt);
+ if (TREE_CODE (rhs) != SSA_NAME
+ || TREE_CODE (algn) != INTEGER_CST)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (rhs);
+ if (!is_gimple_assign (def_stmt)
+ || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
+ return false;
+ if (gimple_assign_rhs1 (def_stmt) != ptr)
+ return false;
+
+ algn = double_int_to_tree (TREE_TYPE (ptr),
+ double_int_not (tree_to_double_int (algn)));
+ gimple_assign_set_rhs_with_ops (gsi, BIT_AND_EXPR, ptr, algn);
+ fold_stmt_inplace (gsi);
+ update_stmt (stmt);
+
+ return true;
+}
+
/* Combine two conversions in a row for the second conversion at *GSI.
Returns 1 if there were any changes made, 2 if cfg-cleanup needs to
run. Else it returns 0. */
@@ -2815,6 +2868,8 @@ ssa_forward_propagate_and_combine (void)
else if (code == PLUS_EXPR
|| code == MINUS_EXPR)
changed = associate_plusminus (&gsi);
+ else if (code == POINTER_PLUS_EXPR)
+ changed = associate_pointerplus (&gsi);
else if (CONVERT_EXPR_CODE_P (code)
|| code == FLOAT_EXPR
|| code == FIX_TRUNC_EXPR)