This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/63783] [4.9/5 Regression] [SH] Miscompilation of boolean negation on SH4 using -O2


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]