diff options
author | Richard Guenther <rguenther@suse.de> | 2012-07-13 13:01:06 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-07-13 13:01:06 +0000 |
commit | a8ab21e5e6bd37732a16f1764d2ab723e9ddd104 (patch) | |
tree | e9e2cb5a1464a5ffa41a29537b01eba96cc0b689 /gcc | |
parent | e8f808b30e83bb6bfa8ff0984fb13b136b3bd4a1 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr53907.c | 14 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 55 |
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) |