I found problem with AVR test instructions such used by c/c++ code (x>0) and demonstrated by testsuite test gcc.c-torture/execute/pr22493-1.c #include <limits.h> extern void abort (); extern void exit (int); void f(int i) { if (i>0) abort(); i = -i; if (i<0) return; abort (); } int main(int argc, char *argv[]) { f(INT_MIN); exit (0); } Compiling this with: avr-gcc -c -mmcu=atmega128 -I. -w -Os -fwrapv -mmcu=atmega128 -Wall -Wstrict-prototypes -Wa,-ahlms=test.s -std=gnu99 test.c -o test.o produces wrong code. An integer test x>0 is translated into RTL: CC0=Rx from which we create AVR assembler code TST Rx which is equivalent to CMP Rx,0 AVR target also have negated_tst RTL patterns to reverse tests in avr_reorg so that we can match the available branches on AVR. For example AVR has BRLT and BRGE but not BRLE and BRGT. So CC0 = Rx Jump LE becomes reorganized as CC0 = NEG:xx(Rx) Jump GE which emits the following code via define_insn "*negated_tst..... CMP 0,Rx BRGE For such test reversals the final code is correct. However, the intermediate RTL used by translation is WRONG CC0=Rx Jump LE is NOT equivalent to CC0 = NEG:xx(Rx) Jump GE For test reversal the problem is hidden - 2 wrongs making a right in this case. BUT the bug appears when we have a normal code sequence such as NEG:xx(Rx) CC0 = Rx which the combine phase will match against the RTL of *negated_tst and result in assembler code of: CMP 0,Rx which is incorrect. Consider the case where Rx= -32768 NEG:HI(-32768) => -32768 CC0 = -32768 => Negative correct! but the replacment: CMP 0,-32768 =>Positive - WRONG The fix is to redefine the "*negated_tst" RTL patterns to use correct COMPARES and have avr_reorg to emit the corrected RTL. (define_insn "*reversed_tsthi" [(set (cc0) (compare (const_int 0) (match_operand:HI 0 "register_operand" "r"))) Test reversals will be unaffected. But now combine won't find any bad RTL. I have not studied to see if the above RTL is ever generated. If it is, it is perfectly safe.
Created attachment 15945 [details] Patch to target files http://gcc.gnu.org/ml/gcc-patches/2008-07/msg00391.html
Subject: Bug 36609 Author: hutchinsonandy Date: Mon Sep 8 22:25:42 2008 New Revision: 140124 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140124 Log: PR target/36609 * config/avr/avr.c (avr_reorg): Create RTL for reversed compare with zero. * config/avr/avr.md (QISI) : Define mode iterator. (negated_tst<mode>) : Redefine as split using mode macro. (reversed_tstqi): Define insn as reversed compare with zero. (reversed_tsthi): Ditto. (reversed_tstsi): Ditto. Modified: trunk/gcc/ChangeLog trunk/gcc/config/avr/avr.c trunk/gcc/config/avr/avr.md
4.4 fixed.