Commit ed74d697 by Jakub Jelinek Committed by Jakub Jelinek

fold-const.c (fold_unary_loc): Fold VEC_UNPACK_LO_EXPR...

	* fold-const.c (fold_unary_loc): Fold VEC_UNPACK_LO_EXPR,
	VEC_UNPACK_HI_EXPR, VEC_UNPACK_FLOAT_LO_EXPR and
	VEC_UNPACK_FLOAT_HI_EXPR with VECTOR_CST argument.
	(fold_binary_loc): Fold VEC_PACK_TRUNC_EXPR,
	VEC_PACK_FIX_TRUNC_EXPR, VEC_WIDEN_MULT_LO_EXPR
	and VEC_WIDEN_MULT_HI_EXPR with VECTOR_CST arguments.

	* gcc.dg/vect/vect-122.c: New test.

From-SVN: r181972
parent f8cca67b
2011-12-03 Jakub Jelinek <jakub@redhat.com> 2011-12-03 Jakub Jelinek <jakub@redhat.com>
* fold-const.c (fold_unary_loc): Fold VEC_UNPACK_LO_EXPR,
VEC_UNPACK_HI_EXPR, VEC_UNPACK_FLOAT_LO_EXPR and
VEC_UNPACK_FLOAT_HI_EXPR with VECTOR_CST argument.
(fold_binary_loc): Fold VEC_PACK_TRUNC_EXPR,
VEC_PACK_FIX_TRUNC_EXPR, VEC_WIDEN_MULT_LO_EXPR
and VEC_WIDEN_MULT_HI_EXPR with VECTOR_CST arguments.
PR debug/50317 PR debug/50317
* tree-ssa.c (target_for_debug_bind): Also allow is_gimple_reg_type * tree-ssa.c (target_for_debug_bind): Also allow is_gimple_reg_type
vars that aren't referenced. vars that aren't referenced.
...@@ -7651,6 +7651,8 @@ build_fold_addr_expr_loc (location_t loc, tree t) ...@@ -7651,6 +7651,8 @@ build_fold_addr_expr_loc (location_t loc, tree t)
return build_fold_addr_expr_with_type_loc (loc, t, ptrtype); return build_fold_addr_expr_with_type_loc (loc, t, ptrtype);
} }
static bool vec_cst_ctor_to_array (tree, tree *);
/* Fold a unary expression of code CODE and type TYPE with operand /* Fold a unary expression of code CODE and type TYPE with operand
OP0. Return the folded expression if folding is successful. OP0. Return the folded expression if folding is successful.
Otherwise, return NULL_TREE. */ Otherwise, return NULL_TREE. */
...@@ -8294,6 +8296,44 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) ...@@ -8294,6 +8296,44 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
} }
return NULL_TREE; return NULL_TREE;
case VEC_UNPACK_LO_EXPR:
case VEC_UNPACK_HI_EXPR:
case VEC_UNPACK_FLOAT_LO_EXPR:
case VEC_UNPACK_FLOAT_HI_EXPR:
{
unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
tree *elts, vals = NULL_TREE;
enum tree_code subcode;
gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2);
if (TREE_CODE (arg0) != VECTOR_CST)
return NULL_TREE;
elts = XALLOCAVEC (tree, nelts * 2);
if (!vec_cst_ctor_to_array (arg0, elts))
return NULL_TREE;
if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR
|| code == VEC_UNPACK_FLOAT_LO_EXPR))
elts += nelts;
if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
subcode = NOP_EXPR;
else
subcode = FLOAT_EXPR;
for (i = 0; i < nelts; i++)
{
elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]);
if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
return NULL_TREE;
}
for (i = 0; i < nelts; i++)
vals = tree_cons (NULL_TREE, elts[nelts - i - 1], vals);
return build_vector (type, vals);
}
default: default:
return NULL_TREE; return NULL_TREE;
} /* switch (code) */ } /* switch (code) */
...@@ -13498,6 +13538,73 @@ fold_binary_loc (location_t loc, ...@@ -13498,6 +13538,73 @@ fold_binary_loc (location_t loc,
} }
return NULL_TREE; return NULL_TREE;
case VEC_PACK_TRUNC_EXPR:
case VEC_PACK_FIX_TRUNC_EXPR:
{
unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
tree *elts, vals = NULL_TREE;
gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts / 2
&& TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts / 2);
if (TREE_CODE (arg0) != VECTOR_CST || TREE_CODE (arg1) != VECTOR_CST)
return NULL_TREE;
elts = XALLOCAVEC (tree, nelts);
if (!vec_cst_ctor_to_array (arg0, elts)
|| !vec_cst_ctor_to_array (arg1, elts + nelts / 2))
return NULL_TREE;
for (i = 0; i < nelts; i++)
{
elts[i] = fold_convert_const (code == VEC_PACK_TRUNC_EXPR
? NOP_EXPR : FIX_TRUNC_EXPR,
TREE_TYPE (type), elts[i]);
if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
return NULL_TREE;
}
for (i = 0; i < nelts; i++)
vals = tree_cons (NULL_TREE, elts[nelts - i - 1], vals);
return build_vector (type, vals);
}
case VEC_WIDEN_MULT_LO_EXPR:
case VEC_WIDEN_MULT_HI_EXPR:
{
unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
tree *elts, vals = NULL_TREE;
gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2
&& TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts * 2);
if (TREE_CODE (arg0) != VECTOR_CST || TREE_CODE (arg1) != VECTOR_CST)
return NULL_TREE;
elts = XALLOCAVEC (tree, nelts * 4);
if (!vec_cst_ctor_to_array (arg0, elts)
|| !vec_cst_ctor_to_array (arg1, elts + nelts * 2))
return NULL_TREE;
if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_WIDEN_MULT_LO_EXPR))
elts += nelts;
for (i = 0; i < nelts; i++)
{
elts[i] = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[i]);
elts[i + nelts * 2]
= fold_convert_const (NOP_EXPR, TREE_TYPE (type),
elts[i + nelts * 2]);
if (elts[i] == NULL_TREE || elts[i + nelts * 2] == NULL_TREE)
return NULL_TREE;
elts[i] = const_binop (MULT_EXPR, elts[i], elts[i + nelts * 2]);
if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
return NULL_TREE;
}
for (i = 0; i < nelts; i++)
vals = tree_cons (NULL_TREE, elts[nelts - i - 1], vals);
return build_vector (type, vals);
}
default: default:
return NULL_TREE; return NULL_TREE;
} /* switch (code) */ } /* switch (code) */
......
2011-12-03 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/vect/vect-122.c: New test.
2011-12-03 Tobias Burnus <burnus@net-b.de> 2011-12-03 Tobias Burnus <burnus@net-b.de>
PR fortran/50684 PR fortran/50684
......
#include "tree-vect.h"
#ifndef N
#define N 64
#endif
char a[N];
float b[N];
long long l[N], m[N];
__attribute__((noinline, noclone)) int
f1 (void)
{
int i;
for (i = 0; i < N; i++)
a[i] = i;
}
__attribute__((noinline, noclone)) int
f2 (void)
{
int i;
for (i = 0; i < N; i++)
b[i] = (double) i;
}
__attribute__((noinline, noclone)) int
f3 (void)
{
int i;
for (i = 0; i < N; i++)
l[i] = (long long) i * (i + 7);
}
__attribute__((noinline, noclone)) int
f4 (void)
{
int i;
for (i = 0; i < N; i++)
m[i] = (long long) i * 7;
}
int
main ()
{
int i;
check_vect ();
f1 ();
f2 ();
f3 ();
f4 ();
for (i = 0; i < N; i++)
if (a[i] != i || b[i] != i || l[i] != i * (i + 7LL) || m[i] != i * 7LL)
abort ();
return 0;
}
/* { dg-final { cleanup-tree-dump "vect" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment