summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/cse.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr70903.c38
4 files changed, 54 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2d9d8c17202..6c41321c47a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2016-08-04 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR rtl-optimization/70903
+ * cse.c (cse_insn): If DEST is a paradoxical SUBREG, don't record DEST.
+
2016-08-04 Kugan Vivekanandarajah <kuganv@linaro.org>
* tree-inline.c (remap_ssa_name): Check for POINTER_TYPE_P before
diff --git a/gcc/cse.c b/gcc/cse.c
index 61d2d7e3c3f..0bfd7ff1669 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -5898,15 +5898,7 @@ cse_insn (rtx_insn *insn)
|| GET_MODE (dest) == BLKmode
/* If we didn't put a REG_EQUAL value or a source into the hash
table, there is no point is recording DEST. */
- || sets[i].src_elt == 0
- /* If DEST is a paradoxical SUBREG and SRC is a ZERO_EXTEND
- or SIGN_EXTEND, don't record DEST since it can cause
- some tracking to be wrong.
-
- ??? Think about this more later. */
- || (paradoxical_subreg_p (dest)
- && (GET_CODE (sets[i].src) == SIGN_EXTEND
- || GET_CODE (sets[i].src) == ZERO_EXTEND)))
+ || sets[i].src_elt == 0)
continue;
/* STRICT_LOW_PART isn't part of the value BEING set,
@@ -5925,6 +5917,11 @@ cse_insn (rtx_insn *insn)
sets[i].dest_hash = HASH (dest, GET_MODE (dest));
}
+ /* If DEST is a paradoxical SUBREG, don't record DEST since the bits
+ outside the mode of GET_MODE (SUBREG_REG (dest)) are undefined. */
+ if (paradoxical_subreg_p (dest))
+ continue;
+
elt = insert (dest, sets[i].src_elt,
sets[i].dest_hash, GET_MODE (dest));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b5ccb9a25a1..0b2a7f211a8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-08-04 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR rtl-optimization/70903
+ * gcc.c-torture/execute/pr70903.c: New test.
+
2016-08-04 Martin Liska <mliska@suse.cz>
* gcc.dg/params/params.exp: Replace file exists with
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70903.c b/gcc/testsuite/gcc.c-torture/execute/pr70903.c
new file mode 100644
index 00000000000..6ffd0aa1641
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr70903.c
@@ -0,0 +1,38 @@
+typedef unsigned char V8 __attribute__ ((vector_size (32)));
+typedef unsigned int V32 __attribute__ ((vector_size (32)));
+typedef unsigned long long V64 __attribute__ ((vector_size (32)));
+
+static V32 __attribute__ ((noinline, noclone))
+foo (V64 x)
+{
+ V64 y = (V64)(V8){((V8)(V64){65535, x[0]})[1]};
+ return (V32){y[0], 255};
+}
+
+int main ()
+{
+ V32 x = foo ((V64){});
+// __builtin_printf ("%08x %08x %08x %08x %08x %08x %08x %08x\n", x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]);
+ if (x[1] != 255)
+ __builtin_abort();
+ return 0;
+}
+typedef unsigned char V8 __attribute__ ((vector_size (32)));
+typedef unsigned int V32 __attribute__ ((vector_size (32)));
+typedef unsigned long long V64 __attribute__ ((vector_size (32)));
+
+static V32 __attribute__ ((noinline, noclone))
+foo (V64 x)
+{
+ V64 y = (V64)(V8){((V8)(V64){65535, x[0]})[1]};
+ return (V32){y[0], 255};
+}
+
+int main ()
+{
+ V32 x = foo ((V64){});
+// __builtin_printf ("%08x %08x %08x %08x %08x %08x %08x %08x\n", x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]);
+ if (x[1] != 255)
+ __builtin_abort();
+ return 0;
+}