]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR target/77326 ([avr] Invalid optimization omits comparison)
authorGeorg-Johann Lay <avr@gjlay.de>
Wed, 21 Sep 2016 14:11:59 +0000 (14:11 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Wed, 21 Sep 2016 14:11:59 +0000 (14:11 +0000)
gcc/
Backport from 2016-09-21 trunk r240306.
PR target/77326
* config/avr/avr.c (hard-reg-set.h): Move #include up in front
of rtl.h to that HARD_CONST is defined in rtl.h.
(avr_notice_update_cc) [CC_NONE]: If insn touches some regs
mentioned in cc_status, do CC_STATUS_INIT.

gcc/testsuite/
Backport from 2016-09-21 trunk r240306.
PR target/77326
* gcc.target/avr/torture/pr77326.c: New test.

From-SVN: r240315

gcc/ChangeLog
gcc/config/avr/avr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/avr/torture/pr77326.c [new file with mode: 0644]

index bba6a7cf067fe6a718e80ac28d7bdaaf750c37ce..5179f9894fa59db3d7d122cfaa372303b2bb66db 100644 (file)
@@ -1,3 +1,13 @@
+2016-09-21  Georg-Johann Lay  <avr@gjlay.de>
+
+       Backport from 2016-09-21 trunk r240306.
+
+       PR target/77326
+       * config/avr/avr.c (hard-reg-set.h): Move #include up in front
+       of rtl.h to that HARD_CONST is defined in rtl.h.
+       (avr_notice_update_cc) [CC_NONE]: If insn touches some regs
+       mentioned in cc_status, do CC_STATUS_INIT.
+
 2016-09-16  Jonathan Wakely  <jwakely@redhat.com>
 
        * doc/extend.texi (Integer Overflow Builtins): Fix type of out
index 75cdd3b30c0756be7372e938f1eb7c3b40308719..140356cc3ac893d69881d507ec4c5d09b2277455 100644 (file)
@@ -22,9 +22,9 @@
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "hard-reg-set.h"
 #include "rtl.h"
 #include "regs.h"
-#include "hard-reg-set.h"
 #include "insn-config.h"
 #include "conditions.h"
 #include "insn-attr.h"
@@ -2526,8 +2526,44 @@ avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx_insn *insn)
       break;
 
     case CC_NONE:
-      /* Insn does not affect CC at all.  */
-      break;
+      /* Insn does not affect CC at all, but it might set some registers
+         that are stored in cc_status.  If such a register is affected by
+         the current insn, for example by means of a SET or a CLOBBER,
+         then we must reset cc_status; cf. PR77326.
+
+         Unfortunately, set_of cannot be used as reg_overlap_mentioned_p
+         will abort on COMPARE (which might be found in cc_status.value1/2).
+         Thus work out the registers set by the insn and regs mentioned
+         in cc_status.value1/2.  */
+
+      if (cc_status.value1
+          || cc_status.value2)
+        {
+          HARD_REG_SET regs_used;
+          HARD_REG_SET regs_set;
+          CLEAR_HARD_REG_SET (regs_used);
+
+          if (cc_status.value1
+              && !CONSTANT_P (cc_status.value1))
+            {
+              find_all_hard_regs (cc_status.value1, &regs_used);
+            }
+
+          if (cc_status.value2
+              && !CONSTANT_P (cc_status.value2))
+            {
+              find_all_hard_regs (cc_status.value2, &regs_used);
+            }
+
+          find_all_hard_reg_sets (insn, &regs_set, false);
+
+          if (hard_reg_set_intersect_p (regs_used, regs_set))
+            {
+              CC_STATUS_INIT;
+            }
+        }
+
+      break; // CC_NONE
 
     case CC_SET_N:
       CC_STATUS_INIT;
index ecb45557176f1192a26e18fb1e15bb889eac4439..899393d60f17a32033755372156e85aae165ac6d 100644 (file)
@@ -1,3 +1,10 @@
+2016-09-21  Georg-Johann Lay  <avr@gjlay.de>
+
+       Backport from 2016-09-21 trunk r240306.
+
+       PR target/77326
+       * gcc.target/avr/torture/pr77326.c: New test.
+
 2016-09-07  Dominique d'Humieres  <dominiq@lps.ens.fr>
 
        PR debug/57519
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr77326.c b/gcc/testsuite/gcc.target/avr/torture/pr77326.c
new file mode 100644 (file)
index 0000000..7fe11ec
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-Wl,--defsym,test1=0" } */
+
+extern void test1 (void) __attribute__((weak));
+
+__attribute__((noinline,noclone))
+static void va_pseudo (int flag, ...)
+{
+  __asm ("nop":);
+}
+
+__attribute__((noinline,noclone))
+static void func (void)
+{
+  va_pseudo (0, 0, 0, 0);
+
+  if (test1)
+    __builtin_abort ();
+}
+
+int main (void)
+{
+  func();
+  __builtin_exit (0);
+  return 0;
+}