diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr90579.c | 7 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.cc | 22 |
3 files changed, 53 insertions, 5 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c new file mode 100644 index 0000000..f80baf3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +struct vec_char_16 +{ + unsigned char raw[2]; +}; + +static inline struct vec_char_16 +Dup128VecFromValues(unsigned char t0, unsigned char t1) +{ + struct vec_char_16 result; + result.raw[0] = t0; + result.raw[1] = t1; + return result; +} + +int f(unsigned char t0, unsigned char t1) +{ + struct vec_char_16 a = Dup128VecFromValues(t0, t1); + struct vec_char_16 b; + __builtin_memcpy(&b, &a, sizeof(a)); + return b.raw[0] + b.raw[1]; +} + +/* Ideally we'd optimize this at FRE1 time but we only replace + the loads from b.raw[] with BIT_FIELD_REFs which get optimized + only later in the next FRE. */ +/* { dg-final { scan-tree-dump-not "MEM" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr90579.c b/gcc/testsuite/gcc.target/i386/pr90579.c index ab48a44..bd2fd33 100644 --- a/gcc/testsuite/gcc.target/i386/pr90579.c +++ b/gcc/testsuite/gcc.target/i386/pr90579.c @@ -16,8 +16,5 @@ loop (int k, double x) return t; } -/* Verify we end up with scalar loads from r for the final sum. */ -/* { dg-final { scan-assembler "vaddsd\tr\\\+40" } } */ -/* { dg-final { scan-assembler "vaddsd\tr\\\+32" } } */ -/* { dg-final { scan-assembler "vaddsd\tr\\\+24" } } */ -/* { dg-final { scan-assembler "vaddsd\tr\\\+16" } } */ +/* Verify we end up with no loads from r. */ +/* { dg-final { scan-assembler-not "v\[ma\]\[^\t \]+\tr" } } */ diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index 00315d1..1c113f8 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -5633,6 +5633,28 @@ visit_nary_op (tree lhs, gassign *stmt) } } break; + case BIT_FIELD_REF: + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME) + { + tree op0 = TREE_OPERAND (rhs1, 0); + gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op0)); + if (ass + && !gimple_has_volatile_ops (ass) + && vn_get_stmt_kind (ass) == VN_REFERENCE) + { + tree last_vuse = gimple_vuse (ass); + tree op = build3 (BIT_FIELD_REF, TREE_TYPE (rhs1), + gimple_assign_rhs1 (ass), + TREE_OPERAND (rhs1, 1), TREE_OPERAND (rhs1, 2)); + tree result = vn_reference_lookup (op, gimple_vuse (ass), + default_vn_walk_kind, + NULL, true, &last_vuse); + if (result + && useless_type_conversion_p (type, TREE_TYPE (result))) + return set_ssa_val_to (lhs, result); + } + } + break; case TRUNC_DIV_EXPR: if (TYPE_UNSIGNED (type)) break; |