diff options
author | Marc Glisse <marc.glisse@inria.fr> | 2014-11-03 11:36:35 +0100 |
---|---|---|
committer | Marc Glisse <glisse@gcc.gnu.org> | 2014-11-03 10:36:35 +0000 |
commit | b25b35c4ca7edf62118660048d5a7672653644f4 (patch) | |
tree | 7670d3794926bbfd749928ce3dc942b7d5e44ef7 /gcc | |
parent | 7629320a5362a2f0b3acf21bdd0a4dd39be21fc5 (diff) | |
download | gcc-b25b35c4ca7edf62118660048d5a7672653644f4.zip gcc-b25b35c4ca7edf62118660048d5a7672653644f4.tar.gz gcc-b25b35c4ca7edf62118660048d5a7672653644f4.tar.bz2 |
re PR tree-optimization/63666 (FAIL: gcc.dg/vect/pr45752.c (internal compiler error))
2014-11-03 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/63666
* fold-const.c: Include "optabs.h".
(fold_ternary_loc) <VEC_PERM_EXPR>: Avoid canonicalizing a
can_vec_perm_p permutation to one that is not.
From-SVN: r217033
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fold-const.c | 32 |
2 files changed, 29 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bcfbd9b..f31c42b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-11-03 Marc Glisse <marc.glisse@inria.fr> + + PR tree-optimization/63666 + * fold-const.c: Include "optabs.h". + (fold_ternary_loc) <VEC_PERM_EXPR>: Avoid canonicalizing a + can_vec_perm_p permutation to one that is not. + 2014-11-03 Zhenqiang Chen <zhenqiang.chen@arm.com> * ifcvt.c (noce_try_store_flag_mask): Check rtx cost. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6258295..78d5182 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-ref.h" #include "cgraph.h" #include "generic-match.h" +#include "optabs.h" /* Nonzero if we are folding constants inside an initializer; zero otherwise. */ @@ -14196,16 +14197,19 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, case VEC_PERM_EXPR: if (TREE_CODE (arg2) == VECTOR_CST) { - unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i, mask; - unsigned char *sel = XALLOCAVEC (unsigned char, nelts); + unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i, mask, mask2; + unsigned char *sel = XALLOCAVEC (unsigned char, 2 * nelts); + unsigned char *sel2 = sel + nelts; bool need_mask_canon = false; + bool need_mask_canon2 = false; bool all_in_vec0 = true; bool all_in_vec1 = true; bool maybe_identity = true; bool single_arg = (op0 == op1); bool changed = false; - mask = single_arg ? (nelts - 1) : (2 * nelts - 1); + mask2 = 2 * nelts - 1; + mask = single_arg ? (nelts - 1) : mask2; gcc_assert (nelts == VECTOR_CST_NELTS (arg2)); for (i = 0; i < nelts; i++) { @@ -14216,13 +14220,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, /* Make sure that the perm value is in an acceptable range. */ wide_int t = val; - if (wi::gtu_p (t, mask)) - { - need_mask_canon = true; - sel[i] = t.to_uhwi () & mask; - } - else - sel[i] = t.to_uhwi (); + need_mask_canon |= wi::gtu_p (t, mask); + need_mask_canon2 |= wi::gtu_p (t, mask2); + sel[i] = t.to_uhwi () & mask; + sel2[i] = t.to_uhwi () & mask2; if (sel[i] < nelts) all_in_vec1 = false; @@ -14264,6 +14265,17 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, if (op0 == op1 && !single_arg) changed = true; + /* Some targets are deficient and fail to expand a single + argument permutation while still allowing an equivalent + 2-argument version. */ + if (need_mask_canon && arg2 == op2 + && !can_vec_perm_p (TYPE_MODE (type), false, sel) + && can_vec_perm_p (TYPE_MODE (type), false, sel2)) + { + need_mask_canon = need_mask_canon2; + sel = sel2; + } + if (need_mask_canon && arg2 == op2) { tree *tsel = XALLOCAVEC (tree, nelts); |