diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2016-09-21 09:17:32 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2016-09-21 09:17:32 +0000 |
commit | bc084f84b3baee7b9fdc73cc05b6aa8adf1e97e5 (patch) | |
tree | de1b810bcf4ee0b024d117dbedd3ed67f5be8921 /gcc | |
parent | c075003a1fc901d487c4cca0b10847d8fc1135fb (diff) | |
download | gcc-bc084f84b3baee7b9fdc73cc05b6aa8adf1e97e5.zip gcc-bc084f84b3baee7b9fdc73cc05b6aa8adf1e97e5.tar.gz gcc-bc084f84b3baee7b9fdc73cc05b6aa8adf1e97e5.tar.bz2 |
re PR target/77326 ([avr] Invalid optimization omits comparison)
gcc/
PR target/77326
* config/avr/avr.c (avr_notice_update_cc) [CC_NONE]: If insn
touches some regs mentioned in cc_status, do CC_STATUS_INIT.
gcc/testsuite/
PR target/77326
* gcc.target/avr/torture/pr77326.c: New test.
From-SVN: r240306
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/avr/torture/pr77326.c | 26 |
4 files changed, 75 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7fe0847..b7c06f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-09-21 Georg-Johann Lay <avr@gjlay.de> + + PR target/77326 + * config/avr/avr.c (avr_notice_update_cc) [CC_NONE]: If insn + touches some regs mentioned in cc_status, do CC_STATUS_INIT. + 2016-09-21 Richard Biener <rguenther@suse.de> PR tree-optimization/77648 diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 148a61d..5ac65b7 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -2511,8 +2511,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, ®s_used); + } + + if (cc_status.value2 + && !CONSTANT_P (cc_status.value2)) + { + find_all_hard_regs (cc_status.value2, ®s_used); + } + + find_all_hard_reg_sets (insn, ®s_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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index adc6422..bc9d2b0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-09-21 Georg-Johann Lay <avr@gjlay.de> + + PR target/77326 + * gcc.target/avr/torture/pr77326.c: New test. + 2016-09-21 Louis Krupp <louis.krupp@zoho.com> * gfortran.dg/pr68078.f90: Run on x86_64_*_linux* only. diff --git a/gcc/testsuite/gcc.target/avr/torture/pr77326.c b/gcc/testsuite/gcc.target/avr/torture/pr77326.c new file mode 100644 index 0000000..7fe11ec --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr77326.c @@ -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; +} |