From ed74d6972b1370588186762f7a787623d53d3140 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 3 Dec 2011 17:41:23 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 ++ gcc/fold-const.c | 107 +++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/vect/vect-122.c | 59 +++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-122.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 178e2224088..82031fc32ab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2011-12-03 Jakub Jelinek + * 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 * tree-ssa.c (target_for_debug_bind): Also allow is_gimple_reg_type vars that aren't referenced. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 8f31a5fdb0e..a32ea9000e6 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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); } +static bool vec_cst_ctor_to_array (tree, tree *); + /* Fold a unary expression of code CODE and type TYPE with operand OP0. Return the folded expression if folding is successful. Otherwise, return NULL_TREE. */ @@ -8294,6 +8296,44 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) } 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: return NULL_TREE; } /* switch (code) */ @@ -13498,6 +13538,73 @@ fold_binary_loc (location_t loc, } 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: return NULL_TREE; } /* switch (code) */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3b03cf7cd95..ffe51d3e9bc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-12-03 Jakub Jelinek + + * gcc.dg/vect/vect-122.c: New test. + 2011-12-03 Tobias Burnus PR fortran/50684 diff --git a/gcc/testsuite/gcc.dg/vect/vect-122.c b/gcc/testsuite/gcc.dg/vect/vect-122.c new file mode 100644 index 00000000000..4cbdd0f7221 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-122.c @@ -0,0 +1,59 @@ +#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" } } */ -- 2.30.2