This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Problem of moving DImode data with no 'movdi' pattern defined
- From: Jie Zhang <zhangjie at magima dot com dot cn>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 28 Apr 2003 17:35:11 +0800
- Subject: 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