This is the mail archive of the gcc@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]

Problem of moving DImode data with no 'movdi' pattern defined


I found gcc (gcc-3_3-branch) generated uncorrected code for moving DImode data with no 'movdi' pattern defined when I retargetting it to a new chip. With -O3 option, gcc generates following rtls (just before cse, generated when compiling testsuite/gcc.c-torture/execute/20000717-2.c):

 ...
 (insn 10 45 13 0 0x40018370 (set (reg/f:SI 41)
         (symbol_ref/u:SI ("*.LC0"))) -1 (nil)
     (expr_list:REG_EQUAL (symbol_ref/u:SI ("*.LC0"))
         (nil)))

 (insn 13 10 11 0 0x40018370 (clobber (reg/v:DI 40)) -1 (nil)
     (nil))

 (insn 11 13 12 0 0x40018370 (set (subreg:SI (reg/v:DI 40) 0)
         (mem/u/f:SI (reg/f:SI 41) [2 S4 A32])) -1 (nil)
     (nil))

(insn 12 11 17 0 0x40018370 (set (subreg:SI (reg/v:DI 40) 4)
(mem/u/f:SI (plus:SI (reg/f:SI 41)
(const_int 4 [0x4])) [2 S4 A32])) -1 (nil)
(expr_list:REG_EQUAL (const_double -1 [0xffffffff] 1 [0x1] 0 [0x0] 0 [0x0] 0 [0x0] 0 [0x0])
(nil)))


 (insn 17 12 18 0 0x40018370 (set (reg:SI 42)
         (subreg:SI (reg/v:DI 40) 4)) -1 (nil)
     (nil))

 (jump_insn 18 17 46 0 0x40018370 (set (pc)
         (if_then_else (gt:SI (reg:SI 42)
                 (const_int 1 [0x1]))
             (label_ref 32)
             (pc))) 32 {*bgt_insn} (nil)
     (expr_list:REG_BR_PRED (concat (const_int 8 [0x8])
             (const_int 100 [0x64]))
         (nil)))
 ;; End of basic block 0, registers live:
  (nil)

 ;; Start of basic block 1, registers live: (nil)
 (note 46 18 19 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

 (insn 19 46 20 1 0x40018370 (set (reg:SI 43)
         (subreg:SI (reg/v:DI 40) 4)) -1 (nil)
     (nil))

 (jump_insn 20 19 47 1 0x40018370 (set (pc)
         (if_then_else (ne:SI (reg:SI 43)
                 (const_int 1 [0x1]))
             (label_ref 27)
             (pc))) -1 (nil)
     (expr_list:REG_BR_PRED (concat (const_int 8 [0x8])
             (const_int 100 [0x64]))
         (nil)))
 ...

REG_EQUAL note in insn 12 refers to (subreg:SI (reg/v:DI 40) 4) instead of (reg/v:DI 40). Then cse pass will incorrectly infer that (reg:SI 42) and (reg:SI 43) are equal to (const_double -1 [0xffffffff] 1 [0x1] 0 [0x0] 0 [0x0] 0 [0x0] 0 [0x0]). After cse, jump_insn 20 will be turned into a wrong rtx

(set (pc) (label_ref 27))

although jump_insn 18 turned into a right rtx

(set (pc) (pc))

Although defining 'movdi' pattern can avoid this problem, I think we should give correct notes to all insns that generated for moving DImode data. An alternative is using 'strict_low_part' as following:

 (insn 12 11 17 0 0x40018370 (set (subreg:SI (reg/v:DI 40) 4)
         (mem/u/f:SI (plus:SI (reg/f:SI 41)
                 (const_int 4 [0x4])) [2 S4 A32])) -1 (nil)

(insn 11 13 12 0 0x40018370 (set (strict_low_part (subreg:SI (reg/v:DI 40) 0))
(mem/u/f:SI (reg/f:SI 41) [2 S4 A32])) -1 (nil)
(nil)) (expr_list:REG_EQUAL (const_double -1 [0xffffffff] 1 [0x1] 0 [0x0] 0 [0x0] 0 [0x0] 0 [0x0])
(nil)))



- Jie




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