aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-09-15 17:54:04 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-09-15 17:54:04 +0200
commita1189286e5dedc4ab4aacda95216b047017cd3cf (patch)
treea04038ed07d498e752afbd26f1ad98c025f14411 /gcc
parent681f5b7cc8e80ef09f4692fac5bf3824e4854d54 (diff)
downloadgcc-a1189286e5dedc4ab4aacda95216b047017cd3cf.zip
gcc-a1189286e5dedc4ab4aacda95216b047017cd3cf.tar.gz
gcc-a1189286e5dedc4ab4aacda95216b047017cd3cf.tar.bz2
re PR rtl-optimization/82192 (gcc produces incorrect code with -O2 and bit-field)
PR rtl-optimization/82192 * combine.c (make_extraction): Don't look through non-paradoxical SUBREGs or TRUNCATE if pos + len is or might be bigger than inner's mode. * gcc.c-torture/execute/pr82192.c: New test. From-SVN: r252824
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/combine.c16
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr82192.c22
4 files changed, 48 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 509742a..8c9988f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-09-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/82192
+ * combine.c (make_extraction): Don't look through non-paradoxical
+ SUBREGs or TRUNCATE if pos + len is or might be bigger than
+ inner's mode.
+
2017-09-15 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
diff --git a/gcc/combine.c b/gcc/combine.c
index ccfee26..e502fa1 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7442,7 +7442,14 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
if (pos_rtx && CONST_INT_P (pos_rtx))
pos = INTVAL (pos_rtx), pos_rtx = 0;
- if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
+ if (GET_CODE (inner) == SUBREG
+ && subreg_lowpart_p (inner)
+ && (paradoxical_subreg_p (inner)
+ /* If trying or potentionally trying to extract
+ bits outside of is_mode, don't look through
+ non-paradoxical SUBREGs. See PR82192. */
+ || (pos_rtx == NULL_RTX
+ && pos + len <= GET_MODE_PRECISION (is_mode))))
{
/* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...),
consider just the QI as the memory to extract from.
@@ -7468,7 +7475,12 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
if (new_rtx != 0)
return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1));
}
- else if (GET_CODE (inner) == TRUNCATE)
+ else if (GET_CODE (inner) == TRUNCATE
+ /* If trying or potentionally trying to extract
+ bits outside of is_mode, don't look through
+ TRUNCATE. See PR82192. */
+ && pos_rtx == NULL_RTX
+ && pos + len <= GET_MODE_PRECISION (is_mode))
inner = XEXP (inner, 0);
inner_mode = GET_MODE (inner);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cd3f7a9..eadffc1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-09-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/82192
+ * gcc.c-torture/execute/pr82192.c: New test.
+
2017-09-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/82217
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr82192.c b/gcc/testsuite/gcc.c-torture/execute/pr82192.c
new file mode 100644
index 0000000..9e56e20
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr82192.c
@@ -0,0 +1,22 @@
+/* PR rtl-optimization/82192 */
+
+unsigned long long int a = 0x95dd3d896f7422e2ULL;
+struct S { unsigned int m : 13; } b;
+
+__attribute__((noinline, noclone)) void
+foo (void)
+{
+ b.m = ((unsigned) a) >> (0x644eee9667723bf7LL
+ | a & ~0xdee27af8U) - 0x644eee9667763bd8LL;
+}
+
+int
+main ()
+{
+ if (__INT_MAX__ != 0x7fffffffULL)
+ return 0;
+ foo ();
+ if (b.m != 0)
+ __builtin_abort ();
+ return 0;
+}