aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2014-11-03 11:36:35 +0100
committerMarc Glisse <glisse@gcc.gnu.org>2014-11-03 10:36:35 +0000
commitb25b35c4ca7edf62118660048d5a7672653644f4 (patch)
tree7670d3794926bbfd749928ce3dc942b7d5e44ef7
parent7629320a5362a2f0b3acf21bdd0a4dd39be21fc5 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c32
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);