backport: re PR target/61055 ([avr] wrong test instruction after increment with -O1)

gcc/
	Backport from 2014-05-09 trunk r210267
	PR target/61055
	* config/avr/avr.md (cc): Add new attribute set_vzn.
	(addqi3, 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 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: r210270
This commit is contained in:
Georg-Johann Lay 2014-05-09 11:34:46 +00:00 committed by Georg-Johann Lay
parent 856853f1f3
commit 1eaf9276cb
5 changed files with 119 additions and 4 deletions

View 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, 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 set cc0 to CC_CLOBBER.
2014-05-08 Charles Baylis <charles.baylis@linaro.org>
Backport from mainline

View File

@ -2175,6 +2175,12 @@ 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
@ -5949,7 +5955,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++;
@ -5971,6 +5977,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;
}

View File

@ -90,7 +90,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_vzn,set_zn,set_n,compare,clobber,
out_plus, out_plus_noclobber,ldi"
(const_string "none"))
@ -1056,7 +1056,7 @@
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")])
(define_expand "addhi3"
@ -3876,7 +3876,7 @@
""
"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")

View 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-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline

View File

@ -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;
}