This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug other/54330] New: Wrong optimization for code from fixed-bit.c
- 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: Mon, 20 Aug 2012 14:08:40 +0000
- Subject: [Bug other/54330] New: Wrong optimization for code from fixed-bit.c
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54330
Bug #: 54330
Summary: Wrong optimization for code from fixed-bit.c
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: other
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: gjl@gcc.gnu.org
Host: i686-pc-linux-gnu
Target: avr
Build: i686-pc-linux-gnu
Created attachment 28056
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=28056
fixed-bit-bug.c: preprocessed bit for fixed.bit.c::__satfractudadq
This is a wrong code bug seen while implementing the ISO/IED TR18037
fixed-point support for AVR.
== compile ==
$ avr-gcc fixed-bit-bug.c -mmcu=atmega128 -Os -S -fdump-rtl-expand-details
== configure ==
$ ../../gcc.gnu.org/trunk/configure --target=avr
--prefix=/local/gnu/install/gcc-4.8 --disable-nls --with-dwarf2
--enable-target-optspace=yes --enable-languages=c,c++
== Bug ==
The .expand dump contains a wrong insn, a GTU branch instead of a LEU branch:
The code tests if the high bit of a shift result is set by comparing >
0x7fffffffffffffff. If the value is less-or-equal, the saturation against 0
must be skipped (goto #76), but the GTU leads to a reversal of the condition.
The block that saturates is BB6:
(insn 104 103 105 5 (parallel [
(set (cc0)
(compare (reg:DI 18 r18)
(const_double -1 [0xffffffff] 2147483647 [0x7fffffff] 0 [0]
0 [0] 0 [0] 0 [0])))
(clobber (scratch:QI))
]) fixed-bit-bug.c:56 -1
(nil))
(jump_insn 105 104 132 5 (set (pc)
(if_then_else (gtu (cc0)
(const_int 0 [0]))
(label_ref 76)
(pc))) fixed-bit-bug.c:56 -1
(expr_list:REG_BR_PROB (const_int 6100 [0x17d4])
(nil))
-> 76)
(note 132 105 29 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
(insn 29 132 21 6 (clobber (reg/v:DI 42 [ low ])) fixed-bit-bug.c:56 -1
(nil))
(insn 21 29 22 6 (set (subreg:QI (reg/v:DI 42 [ low ]) 0)
(const_int 0 [0])) fixed-bit-bug.c:56 -1
(nil))
All of the following changes lead to correct code, u.e. LEU instead of GTU:
* -O1 instead of -O0
* -fno-builtin-memcpy
* Using DI mode instead of DQ resp. DA mode, see the respective #define in the
attaches test case.
Correct code will look like that:
(jump_insn 91 90 132 4 (set (pc)
(if_then_else (leu (cc0)
(const_int 0 [0]))
(label_ref:HI 102)
(pc))) 444 {difficult_branch}
(expr_list:REG_BR_PROB (const_int 5000 [0x1388])
(nil))
-> 102)
(note 132 91 100 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
(insn 100 132 92 5 (clobber (reg/v:DI 42 [ low ])) -1
(nil))
(insn 92 100 93 5 (set (subreg:QI (reg/v:DI 42 [ low ]) 0)
(const_int -1 [0xffffffff])) -1
(nil))