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/27182] [4.1 regression] SH: wrong-code generation



------- Comment #2 from kkojima at gcc dot gnu dot org  2006-04-19 12:42 -------
I'd like to add Joern to the CC list.

I've looked the rtl dumps for the testcase.  It seems that
the wrong code is generated during the peephole2 optimization.
The corresponding part of .41.csa dump is:

(insn:HI 1275 1768 2254 181 sql_select4.cc:515 (set (reg/f:SI 2 r2 [670])
        (reg:SI 1 r1 [656])) 172 {movsi_ie} (insn_list:REG_DEP_TRUE 1267 (nil))
    (nil))

  (insn 2254 1275 1276 181 sql_select4.cc:515 (set (reg:SI 6 r6)
        (mem/f/c:SI (plus:SI (reg/f:SI 14 r14)
                (const_int 52 [0x34])) [292 s+0 S4 A32])) 172 {movsi_ie} (nil)
    (nil))

(insn:HI 1276 2254 1769 181 sql_select4.cc:515 (set (mem/s/f:SI (pre_dec:SI
(reg/f:SI 2 r2 [670])) [6 <variable>.table+0 S4 A32])
        (reg:SI 6 r6)) 172 {movsi_ie} (insn_list:REG_DEP_TRUE 1275 (nil))
    (expr_list:REG_DEAD (reg:SI 6 r6)
        (expr_list:REG_UNUSED (reg/f:SI 2 r2 [670])
            (expr_list:REG_INC (reg/f:SI 2 r2 [670])
                (nil)))))

(note 1769 1276 1772 181 ("sql_select4.cc") 514)

(insn 1772 1769 1269 181 sql_select4.cc:514 (set (reg:SI 2 r2 [666])
        (const_int 0 [0x0])) 172 {movsi_ie} (nil)
    (expr_list:REG_EQUIV (const_int 0 [0x0])
        (nil)))

(insn:HI 1269 1772 1770 181 sql_select4.cc:514 (set (mem/s/f:SI (reg:SI 1 r1
[656]) [16 <variable>.key+0 S4 A32])
        (reg:SI 2 r2 [666])) 172 {movsi_ie} (insn_list:REG_DEP_TRUE 1268
(insn_list:REG_DEP_TRUE 1267 (nil)))
    (expr_list:REG_DEAD (reg:SI 2 r2 [666])
        (expr_list:REG_DEAD (reg:SI 1 r1 [656])
            (expr_list:REG_EQUAL (const_int 0 [0x0])
                (nil)))))

and peephole2 changes these in .42.peephole2 to:

(insn 2640 1768 2641 181 sql_select4.cc:515 (set (reg/f:SI 2 r2 [670])
        (mem/f/c:SI (plus:SI (reg/f:SI 14 r14)
                (const_int 52 [0x34])) [292 s+0 S4 A32])) 172 {movsi_ie} (nil)
    (nil))

(insn 2641 2640 1769 181 sql_select4.cc:515 (set (mem/s/f:SI (pre_dec:SI
(reg:SI 1 r1 [656])) [6 <variable>.table+0 S4 A32])
        (reg/f:SI 2 r2 [670])) 172 {movsi_ie} (nil)
    (expr_list:REG_DEAD (reg/f:SI 2 r2 [670])
        (nil)))

(note 1769 2641 1772 181 ("sql_select4.cc") 514)

(insn 1772 1769 1269 181 sql_select4.cc:514 (set (reg:SI 2 r2 [666])
        (const_int 0 [0x0])) 172 {movsi_ie} (nil)
    (expr_list:REG_EQUIV (const_int 0 [0x0])
        (nil)))

(insn:HI 1269 1772 1770 181 sql_select4.cc:514 (set (mem/s/f:SI (reg:SI 1 r1
[656]) [16 <variable>.key+0 S4 A32])
        (reg:SI 2 r2 [666])) 172 {movsi_ie} (insn_list:REG_DEP_TRUE 1268
(insn_list:REG_DEP_TRUE 1267 (nil)))
    (expr_list:REG_DEAD (reg:SI 2 r2 [666])
        (expr_list:REG_DEAD (reg:SI 1 r1 [656])
            (expr_list:REG_EQUAL (const_int 0 [0x0])
                (nil)))))

It looks the define_peephole2 movsicc_true+3

(define_peephole2
  [(set (match_operand 0 "any_register_operand" "")
        (match_operand 1 "any_register_operand" ""))
   (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
   (set (match_operand 4 "" "") (match_operand 5 "" ""))]
  "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
    <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
   && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
   && ! reg_overlap_mentioned_p (operands[0], operands[3])
   && ! reg_overlap_mentioned_p (operands[2], operands[0])
   && ! reg_overlap_mentioned_p (operands[0], operands[1])
   && (REGNO_REG_CLASS (REGNO (operands[0]))
       == REGNO_REG_CLASS (REGNO (operands[2])))
   && (REGNO_REG_CLASS (REGNO (operands[1]))
       == REGNO_REG_CLASS (REGNO (operands[0])))"
  [(set (match_dup 0) (match_dup 3))
   (set (match_dup 4) (match_dup 5))]

causes this change.  In the problematic case, (reg/f:SI 2 r2 [670])
in (mem/s/f:SI (pre_dec:SI (reg/f:SI 2 r2 [670])) is replaced with
(reg:SI 1 r1 [656]) and results a wrong r1 value.  Perhaps this
issue is simply latent in the mainline, though I have no testcases
for the mainline.  I'm testing the patch below to prevent this
peephole2 optimization for such situation.

diff -uprN ORIG/gcc-4_1-branch/gcc/config/sh/sh.md
LOCAL/gcc-4_1-branch/gcc/config/sh/sh.md
--- ORIG/gcc-4_1-branch/gcc/config/sh/sh.md     2006-02-06 21:07:13.000000000
+0900
+++ LOCAL/gcc-4_1-branch/gcc/config/sh/sh.md    2006-04-18 09:06:47.000000000
+0900
@@ -1094,6 +1094,8 @@
   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
+   && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
+   && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
    && ! reg_overlap_mentioned_p (operands[0], operands[3])
    && ! reg_overlap_mentioned_p (operands[2], operands[0])
    && ! reg_overlap_mentioned_p (operands[0], operands[1])


-- 

kkojima at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kkojima at gcc dot gnu dot
                   |                            |org, amylaar at gcc dot gnu
                   |                            |dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27182


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