------- Comment #4 from steven at gcc dot gnu dot org  2007-05-11 18:22 -------
For "convert" the issue is caused by a decision that reload makes, but I don't
understand why.  The .lreg dump is this:

;; Start of basic block 2, registers live: 5 [di] 6 [bp] 7 [sp] 16 [argp] 20
[frame]
;; Pred edge  ENTRY [100.0%]  (fallthru)
(note:HI 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(insn:HI 2 4 3 2 t.c:3 (set (reg/v:SI 59 [ in ])
        (reg:SI 5 di [ in ])) 40 {*movsi_1} (nil)
    (expr_list:REG_DEAD (reg:SI 5 di [ in ])
        (nil)))

(note:HI 3 2 6 2 NOTE_INSN_FUNCTION_BEG)

(insn:HI 6 3 10 2 t.c:3 (set (reg:SF 58 [ <result> ])
        (subreg:SF (reg/v:SI 59 [ in ]) 0)) 90 {*movsf_1}
(insn_list:REG_DEP_TRUE 2 (nil))
    (expr_list:REG_DEAD (reg/v:SI 59 [ in ])
        (nil)))

(insn:HI 10 6 16 2 t.c:7 (set (reg/i:SF 21 xmm0 [ <result> ])
        (reg:SF 58 [ <result> ])) 90 {*movsf_1} (insn_list:REG_DEP_TRUE 6
(nil))
    (expr_list:REG_DEAD (reg:SF 58 [ <result> ])
        (nil)))

(insn:HI 16 10 0 2 t.c:7 (use (reg/i:SF 21 xmm0 [ <result> ])) -1
(insn_list:REG_DEP_TRUE 10 (nil))
    (nil))
;; End of basic block 2, registers live: 6 [bp] 7 [sp] 16 [argp] 20 [frame] 21
[xmm0]
;; Succ edge  EXIT [100.0%]  (fallthru)




Then in .greg we reload things:

;; Function convert (convert)

;; 0 regs to allocate:
;; 58 conflicts: 58 7 21
;; 59 conflicts: 59 5 7

Spilling for insn 6.
Using reg 22 for reload 0
Spilling for insn 6.
Using reg 22 for reload 0

Reloads for insn # 6
Reload 0: reload_in (SF) = (reg:SF 5 di)
        SSE_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine
        reload_in_reg: (subreg:SF (reg/v:SI 5 di [orig:59 in ] [59]) 0)
        reload_reg_rtx: (reg:SF 22 xmm1)
;; Register dispositions:
58 in 21  59 in 5

;; Hard regs used:  5 21 22

(note:HI 1 0 4 NOTE_INSN_DELETED)

;; Start of basic block 2, registers live: 5 [di] 7 [sp]
;; Pred edge  ENTRY [100.0%]  (fallthru)
(note:HI 4 1 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(note:HI 3 4 22 2 NOTE_INSN_FUNCTION_BEG)

(insn 22 3 23 2 t.c:3 (set (mem/c:SF (plus:DI (reg/f:DI 7 sp)
                (const_int -4 [0xfffffffffffffffc])) [0 S4 A8])
        (reg:SF 5 di)) 90 {*movsf_1} (nil)
    (nil))

(insn 23 22 6 2 t.c:3 (set (reg:SF 22 xmm1)
        (mem/c:SF (plus:DI (reg/f:DI 7 sp)
                (const_int -4 [0xfffffffffffffffc])) [0 S4 A8])) 90 {*movsf_1}
(nil)
    (nil))

(insn:HI 6 23 16 2 t.c:3 (set (reg:SF 21 xmm0 [orig:58 <result> ] [58])
        (reg:SF 22 xmm1)) 90 {*movsf_1} (insn_list:REG_DEP_TRUE 2 (nil))
    (nil))

(insn 16 6 21 2 t.c:7 (use (reg/i:SF 21 xmm0 [ <result> ])) -1
(insn_list:REG_DEP_TRUE 10 (nil))
    (nil))
;; End of basic block 2, registers live: 6 [bp] 7 [sp] 16 [argp] 20 [frame] 21
[xmm0]
;; Succ edge  EXIT [100.0%]  (fallthru)

(note 21 16 0 NOTE_INSN_DELETED)


The only reason that I can think of for this problem, by looking at the dumps,
is the rather strange conflict of reg 58 with reg 21 (xmm0).  Reg 58 dies when
it is copied to xmm0 in insn 10, so we should tie the registers and coalesce. 
I'm not sure why we can't resolve this without the extra move.


-- 


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

Reply via email to