https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66156

            Bug ID: 66156
           Summary: [msp430] wrong code generated with -O2 -mlarge (zero
                    extension HI -> SI)
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ronald.wahl at raritan dot com
  Target Milestone: ---

Created attachment 35544
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35544&action=edit
C file that is miscompiled

The attached C file is miscompiled by msp-gcc-elf when compiled with
"-mlarge -O2". I see this problem with the current source bundle from TI
as well as current gcc trunk.

The problem is that R13 (containing "val") is prematurely
cleared by a zero_extendhisi2 insn:

; R12 contains pointer to "array"
; R13 contains "val"
        PUSHM.A #1, R10
        PUSHM.A #3, R8
        ; end of prologue
        MOVA    R12, R8
        CMPX.W  #0, &g_flag { JEQ       .L2
        MOVX    &g_second, R12
        ADDA    R12, R12
        ADDA    R8, R12
        MOV.W   @R12, R12

        MOV.W   #0,R13 ; <---- R13 clobbered (by zero_extendhisi2 (insn 12))

        MOV.W   R12, R10
        MOV.W   R13, R11
        MOVX.W  &g_sum, R14
        MOVX.W  &g_sum+2, R15
        SUBX    R10, R14 { SUBCX        R11, R15
.L3:
        MOV.W   R13, R6 ; <---- R13 used after it was clobbered

        MOV.W   #0,R7
        MOV.W   R6, R10
        MOV.W   R7, R11
.L4:
        MOVX.W  #1, &g_flag
        ADD     R10, R14 ; cy
        ADDC    R11, R15
        MOVX    &g_first, R12
        ADDA    R12, R12
        ADDA    R8, R12

        MOV.W   R13, @R12 ; <---- R13 used after it was clobbered

        CMPX.W  #0, &g_flag { JEQ       .L4
        MOVX.W  R14, &g_sum
        MOVX.W  R15, &g_sum+2
        ; start of epilogue
        POPM.A  #3, r8
        POPM.A  #1, r10
        RETA
.L2:
        MOVX.W  &g_sum, R14
        MOVX.W  &g_sum+2, R15
        BRA     #.L3

In msp430.md there is a zero_extendhisi2 isnsn defined as follows:

  ;; Look for cases where integer/pointer conversions are suboptimal due
  ;; to missing patterns, despite us not having opcodes for these
  ;; patterns.  Doing these manually allows for alternate optimization
  ;; paths.
  (define_insn "zero_extendhisi2"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
          (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
    "msp430x"
    "MOV.W\t#0,%H0"
  )

The purpose seems to be in-place zero-extending an operand.

The problem happens during reload right after IRA. During IRA insn 12
(zero_extendhisi2) has r42 as input and r43 as output. Furthermore r39
contains "val". IRA assigns:
r39 -> r13 (HI)
r42 -> r12 (HI)
r43 -> r10 (SI)

But during reload the "zero_extendhisi2" insn defined in msp430.md matches
and zero extends R12 (i.e. clears R13) instead of R10.

Commenting out the insn in msp430.md or adding reload_completed constraint
fixes the issue but may raise the issues again why this insns was defined -
whatever these are.

So what's going on here?

Reply via email to