]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR target/61055 ([avr] wrong test instruction after increment with -O1)
authorGeorg-Johann Lay <avr@gjlay.de>
Fri, 9 May 2014 11:29:58 +0000 (11:29 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Fri, 9 May 2014 11:29:58 +0000 (11:29 +0000)
gcc/
Backport from 2014-05-09 trunk r210267
PR target/61055
* config/avr/avr.md (cc): Add new attribute set_vzn.
(addqi3, addqq3, adduqq3, subqi3, subqq3, subuqq3, negqi2) [cc]:
Set cc insn attribute to set_vzn instead of set_zn for alternatives
with INC, DEC or NEG.
* config/avr/avr.c (avr_notice_update_cc): Handle SET_VZN.
(avr_out_plus_1): ADIW sets cc0 to CC_SET_CZN.
INC, DEC and ADD+ADC set cc0 to CC_CLOBBER.

gcc/testsuite/
Backport from 2014-05-09 trunk r210267
PR target/61055
* gcc.target/avr/torture/pr61055.c: New test.

From-SVN: r210269

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

index c2960259e3b66964c4faf21235b99f6b97bb96ce..f8d30c154aed5c07c98e2dc61c4dc68b983c7d8e 100644 (file)
@@ -1,3 +1,16 @@
+2014-05-09  Georg-Johann Lay  <avr@gjlay.de>
+
+       Backport from 2014-05-09 trunk r210267
+
+       PR target/61055
+       * config/avr/avr.md (cc): Add new attribute set_vzn.
+       (addqi3, addqq3, adduqq3, subqi3, subqq3, subuqq3, negqi2) [cc]:
+       Set cc insn attribute to set_vzn instead of set_zn for alternatives
+       with INC, DEC or NEG.
+       * config/avr/avr.c (avr_notice_update_cc): Handle SET_VZN.
+       (avr_out_plus_1): ADIW sets cc0 to CC_SET_CZN.
+       INC, DEC and ADD+ADC set cc0 to CC_CLOBBER.
+
 2014-05-09  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * builtins.c (expand_builtin_setjmp_receiver): Emit a use of
index 44d8a83e5eac33414d6fc8f49e7364c20dccb39d..05ef3860018f22786bd57999a73cbe91acae83ee 100644 (file)
@@ -2343,6 +2343,12 @@ avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
         }
       break;
 
+    case CC_SET_VZN:
+      /* Insn like INC, DEC, NEG that set Z,N,V.  We currently don't make use
+         of this combination, cf. also PR61055.  */
+      CC_STATUS_INIT;
+      break;
+
     case CC_SET_CZN:
       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
          The V flag may or may not be known but that's ok because
@@ -6278,7 +6284,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
 
   if (REG_P (xop[2]))
     {
-      *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
+      *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_CLOBBER;
 
       for (i = 0; i < n_bytes; i++)
         {
@@ -6387,7 +6393,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
                                op, plen, 1);
 
                   if (n_bytes == 2 && PLUS == code)
-                    *pcc = CC_SET_ZN;
+                    *pcc = CC_SET_CZN;
                 }
 
               i++;
@@ -6410,6 +6416,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
         {
           avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
                        op, plen, 1);
+          *pcc = CC_CLOBBER;
           break;
         }
 
index f2681233acee549114e42dc678777e244e268157..ae2e7651d44edaf83b3cd0659d82ff69163dda9d 100644 (file)
@@ -89,7 +89,7 @@
 (include "constraints.md")
 
 ;; Condition code settings.
-(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
+(define_attr "cc" "none,set_czn,set_zn,set_vzn,set_n,compare,clobber,
                    plus,ldi"
   (const_string "none"))
 
        inc %0\;inc %0
        dec %0\;dec %0"
   [(set_attr "length" "1,1,1,1,2,2")
-   (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
+   (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
 
 ;; "addhi3"
 ;; "addhq3" "adduhq3"
        dec %0\;dec %0
        inc %0\;inc %0"
   [(set_attr "length" "1,1,1,1,2,2")
-   (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
+   (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
 
 ;; "subhi3"
 ;; "subhq3" "subuhq3"
   ""
   "neg %0"
   [(set_attr "length" "1")
-   (set_attr "cc" "set_zn")])
+   (set_attr "cc" "set_vzn")])
 
 (define_insn "*negqihi2"
   [(set (match_operand:HI 0 "register_operand"                        "=r")
index 3dd50b90eb140edac11d8b602007f584803febde..809b14e9217edbf30dd8c3352bbc82f15ec55e64 100644 (file)
@@ -1,3 +1,10 @@
+2014-05-09  Georg-Johann Lay  <avr@gjlay.de>
+
+       Backport from 2014-05-09 trunk r210267
+
+       PR target/61055
+       * gcc.target/avr/torture/pr61055.c: New test.
+
 2014-05-08  Matthias Klose  <doko@ubuntu.com>
 
        PR driver/61106
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr61055.c b/gcc/testsuite/gcc.target/avr/torture/pr61055.c
new file mode 100644 (file)
index 0000000..9dd1f42
--- /dev/null
@@ -0,0 +1,88 @@
+/* { dg-do run } */
+/* { dg-options { -fno-peephole2 } } */
+
+#include <stdlib.h>
+
+typedef __UINT16_TYPE__ uint16_t;
+typedef __INT16_TYPE__  int16_t;
+typedef __UINT8_TYPE__  uint8_t;
+
+uint8_t __attribute__((noinline,noclone))
+fun_inc (uint8_t c0)
+{
+  register uint8_t c asm ("r15") = c0;
+
+  /* Force target value into R15 (lower register)  */
+  asm ("" : "+l" (c));
+
+  c++;
+  if (c >= 0x80)
+    c = 0;
+  
+  asm ("" : "+l" (c));
+
+  return c;
+}
+
+uint8_t __attribute__((noinline,noclone))
+fun_dec (uint8_t c0)
+{
+  register uint8_t c asm ("r15") = c0;
+
+  /* Force target value into R15 (lower register)  */
+  asm ("" : "+l" (c));
+
+  c--;
+  if (c < 0x80)
+    c = 0;
+  
+  asm ("" : "+l" (c));
+
+  return c;
+}
+
+
+uint8_t __attribute__((noinline,noclone))
+fun_neg (uint8_t c0)
+{
+  register uint8_t c asm ("r15") = c0;
+
+  c = -c;
+  if (c >= 0x80)
+    c = 0;
+
+  return c;
+}
+
+uint16_t __attribute__((noinline,noclone))
+fun_adiw (uint16_t c0)
+{
+  register uint16_t c asm ("r24") = c0;
+
+  /* Force target value into R24 (for ADIW) */
+  asm ("" : "+r" (c));
+
+  c += 2;
+  if (c >= 0x8000)
+    c = 0;
+
+  asm ("" : "+r" (c));
+  
+  return c;
+}
+
+
+int main()
+{
+  if (fun_inc (0x7f) != 0)
+    abort();
+  
+  if (fun_neg (0x80) != 0)
+    abort();
+  
+  if (fun_adiw (0x7ffe) != 0)
+    abort();
+
+  exit (0);
+  return 0;
+}