This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/63783] [4.9/5 Regression] [SH] Miscompilation of boolean negation on SH4 using -O2
- From: "gcc-bugzilla at mkarcher dot dialup.fu-berlin.de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sun, 16 Nov 2014 12:20:01 +0000
- Subject: [Bug target/63783] [4.9/5 Regression] [SH] Miscompilation of boolean negation on SH4 using -O2
- Auto-submitted: auto-generated
- References: <bug-63783-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63783
--- Comment #10 from Michael Karcher <gcc-bugzilla at mkarcher dot dialup.fu-berlin.de> ---
Created attachment 33991
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33991&action=edit
Fix logical negation of registers, SImode only
In fact, it turns out, you were right. I implemented the solution you suggest
(quite hacky, as I only implemented it for SImode, I was too lazy to look up
whether there are nice patterns for testing DImode operands into T), and
compared assembler outputs. In fact, the duplicate test instruction is NOT
eliminated in my first patch, but it is with your code after fixing.
So the approach of special-casing compare-to-zero seems to have a positive
effect.
Assembler output:
buggy:
tst r4,r4
bf .L2 ; initial if, jumps if "flag" is nonzero
; Branch for zero "flag"
mov.l .L10,r1 ; loads address of val
mov.l @r1,r1 ; loads value of val
; Common code for zero or non-zero flag
.L3:
tst r1,r1 ; combined test
bt .L8 ; if zero, skip increment
mov.l .L11,r2 ; load address of true_count
mov.l @r2,r1 ; load, increment, store true_count
add #1,r1
mov.l r1,@r2
; Label for skipping increment of true_count
.L8:
rts
.align 1
; branch for non-zero "flag"
.L2:
mov.l .L12,r1 ; load address of decision_result
mov.l @r1,r1 ; load data of decision_result
tst r1,r1 ; tst/movt logical negation before
bra .L3 ; jumping to common code
movt r1
With my earlier patch removing the "compare-to-zero" logic completely, the
assembler output changes as following (CAPS comments on changes):
...
mov.l @r1,r1 ; loads value of val
tst r1,r1 ; TEST ONLY FOR FLAG == 0
; Common code for zero or non-zero flag
.L3:
bt .L8 ; if zero, skip increment
...
tst r1,r1 ; tst/movt logical negation before
movt r1
bra .L3 ; jumping to common code
tst r1,r1 ; TEST ONLY FOR FLAG != 0