char >> 7 is compiled to

LSL reg
SBC reg,reg

which leaves cc0 in a mess because Z-flag is not set by SBC, it's
propagated from LSL.

Patch as obvious, new testcase pass and contains *cmpqi.

Ok to commit?

Johann


gcc/
        PR target/39633
        * config/avr/avr.c (notice_update_cc): For ashiftrt:QI, only
        offsets 1..5 set cc0 in a usable way.

testsuite/
        * gcc.target/avr/torture/pr39633.c: New test case.
Index: testsuite/gcc.target/avr/torture/pr39633.c
===================================================================
--- testsuite/gcc.target/avr/torture/pr39633.c	(revision 0)
+++ testsuite/gcc.target/avr/torture/pr39633.c	(revision 0)
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+
+#include <stdlib.h>
+
+char c = 42;
+
+void __attribute__((noinline,noclone))
+pr39633 (char a)
+{
+  a >>= 7;
+  if (a)
+    c = a;
+}
+
+int main()
+{
+  pr39633 (6);
+
+  if (c != 42)
+    abort();
+
+  exit(0);
+    
+  return 0;
+}
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 176136)
+++ config/avr/avr.c	(working copy)
@@ -1479,9 +1479,8 @@ notice_update_cc (rtx body ATTRIBUTE_UNU
 	    {
 	      rtx x = XEXP (src, 1);
 
-	      if (GET_CODE (x) == CONST_INT
-		  && INTVAL (x) > 0
-		  && INTVAL (x) != 6)
+	      if (CONST_INT_P (x)
+		  && IN_RANGE (INTVAL (x), 1, 5))
 		{
 		  cc_status.value1 = SET_DEST (set);
 		  cc_status.flags |= CC_OVERFLOW_UNUSABLE;

Reply via email to