]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR rtl-optimization/82192 (gcc produces incorrect code with -O2 and...
authorJakub Jelinek <jakub@redhat.com>
Mon, 25 Jun 2018 16:45:10 +0000 (18:45 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 25 Jun 2018 16:45:10 +0000 (18:45 +0200)
Backported from mainline
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.

* gcc.c-torture/execute/pr82192.c: New test.

From-SVN: r262028

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr82192.c [new file with mode: 0644]

index 62309f352e26fe3c601dbf8672984ea581179da5..e0da88cd08c7391d2b85a0a796f630d3b263fb2b 100644 (file)
@@ -7,6 +7,13 @@
        * gimplify.c (gimplify_modify_expr): Don't optimize away zero sized
        lhs from calls if the lhs has addressable type.
 
+       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.
+
 2018-06-23  Richard Sandiford  <richard.sandiford@linaro.org>
 
        PR tree-optimization/85989
index 9b0386c99e7726929a9809ee843664e7c860aaad..c38b57dd38e2a86277c7dbe3788363fc710dd3db 100644 (file)
@@ -7336,7 +7336,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.
@@ -7362,7 +7369,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);
index b382215ba5509c26ffce336e4cf91c18ddb207ec..65ee8dae05e1a627d972df24f77b9f1c29d30a13 100644 (file)
        PR c++/82159
        * g++.dg/opt/pr82159.C: New test.
 
+       2017-09-15  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/82192
+       * gcc.c-torture/execute/pr82192.c: New test.
+
 2018-06-23  Richard Sandiford  <richard.sandiford@linaro.org>
 
        PR tree-optimization/85989
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr82192.c b/gcc/testsuite/gcc.c-torture/execute/pr82192.c
new file mode 100644 (file)
index 0000000..9e56e20
--- /dev/null
@@ -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;
+}