h8300.c (notice_update_cc): Don't assume that recog_data.operands[0] is always associ...
authorKazu Hirata <kazu@cs.umass.edu>
Mon, 20 Jan 2003 06:42:58 +0000 (06:42 +0000)
committerKazu Hirata <kazu@gcc.gnu.org>
Mon, 20 Jan 2003 06:42:58 +0000 (06:42 +0000)
* config/h8300/h8300.c (notice_update_cc): Don't assume that
recog_data.operands[0] is always associated with cc0.

* gcc.c-torture/execute/20030120-1.c: New.

From-SVN: r61498

gcc/ChangeLog
gcc/config/h8300/h8300.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20030120-1.c [new file with mode: 0644]

index 60079157d09c8f4cc5a93acb614a74f95e7d9e47..5e795cee8fae99659791030fd922327526b443bc 100644 (file)
@@ -1,3 +1,8 @@
+2003-01-20  Kazu Hirata  <kazu@cs.umass.edu>
+
+       * config/h8300/h8300.c (notice_update_cc): Don't assume that
+       recog_data.operands[0] is always associated with cc0.
+
 2003-01-19  David Edelsohn  <edelsohn@gnu.org>
 
        * collect2.c (ldgetname): Expand declaration to prototype.
index c98f6e11d6b25c1427e0a0a96a4dbfad8d6fdede..faa924816ed72c56e9ae92fda02e7165553fd70c 100644 (file)
@@ -1710,6 +1710,8 @@ notice_update_cc (body, insn)
      rtx body;
      rtx insn;
 {
+  rtx set;
+
   switch (get_attr_cc (insn))
     {
     case CC_NONE:
@@ -1732,7 +1734,10 @@ notice_update_cc (body, insn)
         that's ok because alter_cond will change tests to use EQ/NE.  */
       CC_STATUS_INIT;
       cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
-      cc_status.value1 = recog_data.operand[0];
+      set = single_set (insn);
+      cc_status.value1 = SET_SRC (set);
+      if (SET_DEST (set) != cc0_rtx)
+       cc_status.value2 = SET_DEST (set);
       break;
 
     case CC_SET_ZNV:
@@ -1741,9 +1746,10 @@ notice_update_cc (body, insn)
         alter_cond will change tests to use EQ/NE.  */
       CC_STATUS_INIT;
       cc_status.flags |= CC_NO_CARRY;
-      cc_status.value1 = recog_data.operand[0];
-      if (GET_CODE (body) == SET && REG_P (SET_SRC (body)))
-       cc_status.value2 = SET_SRC (body);
+      set = single_set (insn);
+      cc_status.value1 = SET_SRC (set);
+      if (SET_DEST (set) != cc0_rtx)
+       cc_status.value2 = SET_DEST (set);
       break;
 
     case CC_COMPARE:
index 71f07f722a64143436142a472ec62df2ad2144b4..79e76c02697b43b6cb9d79326702a2f6cda1ae80 100644 (file)
@@ -1,3 +1,7 @@
+2003-01-20  Kazu Hirata  <kazu@cs.umass.edu>
+
+       * gcc.c-torture/execute/20030120-1.c: New.
+
 2003-01-19  Paolo Carlini  <pcarlini@unitus.it>
 
        * g++.old-deja/g++.pt/typename13.C: Remove XFAIL.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030120-1.c b/gcc/testsuite/gcc.c-torture/execute/20030120-1.c
new file mode 100644 (file)
index 0000000..0ac0ecf
--- /dev/null
@@ -0,0 +1,50 @@
+/* On H8/300 port, NOTICE_UPDATE_CC had a bug that causes the final
+   pass to remove test insns that should be kept.  */
+
+unsigned short
+test1 (unsigned short w)
+{
+  if ((w & 0xff00) == 0)
+    {
+      if (w == 0)
+       w = 2;
+    }
+  return w;
+}
+
+unsigned long
+test2 (unsigned long w)
+{
+  if ((w & 0xffff0000) == 0)
+    {
+      if (w == 0)
+       w = 2;
+    }
+  return w;
+}
+
+int
+test3 (unsigned short a)
+{
+  if (a & 1)
+    return 1;
+  else if (a)
+    return 1;
+  else
+    return 0;
+}
+
+int
+main ()
+{
+  if (test1 (1) != 1)
+    abort ();
+
+  if (test2 (1) != 1)
+    abort ();
+
+  if (test3 (2) != 1)
+    abort ();
+
+  exit (0);
+}