aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/pr90579.c7
-rw-r--r--gcc/tree-ssa-sccvn.cc22
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;