This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/60486] [4.8/4.9 Regression] [avr] superfluous or missing comparision after addition or subtraction
- From: "gjl at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 11 Mar 2014 12:35:43 +0000
- Subject: [Bug target/60486] [4.8/4.9 Regression] [avr] superfluous or missing comparision after addition or subtraction
- Auto-submitted: auto-generated
- References: <bug-60486-4 at http dot gcc dot gnu dot org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60486
Georg-Johann Lay <gjl at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |wrong-code
Component|other |target
Summary|[avr] missed optimization |[4.8/4.9 Regression] [avr]
|on detecting zero flag set |superfluous or missing
| |comparision after addition
| |or subtraction
Known to fail| |4.9.0
--- Comment #5 from Georg-Johann Lay <gjl at gcc dot gnu.org> ---
Target issue.
(In reply to Darryl Piper from comment #4)
> details also posted on avrfreaks.net
I am well aware of this post.
But GCC reports are supposed to be self contained. So here we go:
Root cause is swapped cc_plus and cc_minus in avr.c:avr_out_plus :
/* Work out the shortest sequence. */
avr_out_plus_1 (op, &len_minus, MINUS, &cc_plus, code_sat, sign, out_label);
avr_out_plus_1 (op, &len_plus, PLUS, &cc_minus, code_sat, sign, out_label);
Thus there are also cases where wrong code is generated like the following one:
extern void foo (unsigned);
char v;
void bar (unsigned long z)
{
if (++z == 0)
v = 0;
foo (z);
}
Output is missing the comparison because addsi3 does not set cc0 in a usable
way when is uses the PLUS alternative:
bar:
movw r26,r24 ; 20 *movsi/1 [length = 2]
movw r24,r22
adiw r24,1 ; 6 addsi3/2 [length = 3]
adc r26,__zero_reg__
adc r27,__zero_reg__
brne .L5 ; 8 branch [length = 1]
sts v,__zero_reg__ ; 10 movqi_insn/3 [length = 2]
.L5:
rjmp foo ; 14 call_insn/4 [length = 1]