This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
conditional exec verify_live problem after scheduling
- To: bernds at redhat dot com, gcc-bugs at gcc dot gnu dot org
- Subject: conditional exec verify_live problem after scheduling
- From: Richard Earnshaw <rearnsha at arm dot com>
- Date: Wed, 10 Jan 2001 18:24:38 +0000
- cc: rearnsha at arm dot com
- Organization: ARM Ltd.
- Reply-To: rearnsha at arm dot com
[Arggh! This should have gone to gcc-bugs, not gcc-patches. Sorry about
that]
Bernd,
I've come across the following problem which I think is probably related
to your recent conditional-execution scheduling changes (though it may be
just uncovering an underlying problem from before). The problem is in
newlib/libm/common/s_modf.c when compiling arm-elf and -mhard-float.
Before scheduling we have (I've stripped the note and dead insns out)
[bb 2]
;; Start of basic block 2, registers live: 0 [r0] 1 [r1] 4 [r4] 6 [r6] 7
[r7] 8 [r8] 12 [ip] 13 [sp] 14 [lr] 16 [f0]
(code_label 70 59 298 5 "" "" [0 uses])
(code_label 70 59 298 5 "" "" [0 uses])
(insn 325 82 326 (set (reg:SI 3 r3 [49])
(const_int 16777215 [0xffffff])) 175 {*arm_movsi_insn} (nil)
(nil))
(insn 326 325 77 (set (reg:SI 3 r3 [49])
(plus:SI (reg:SI 3 r3 [49])
(const_int -15728640 [0xff100000]))) 4 {*arm_addsi3}
(insn_list 325 (insn_list 325 (nil)))
(nil))
(insn 77 326 78 (set (reg/v:SI 3 r3 [37])
(ashiftrt:SI (reg:SI 3 r3 [49])
(reg/v:SI 1 r1 [36]))) 119 {*arm_shiftsi3} (insn_list 326
(insn_list 326 (nil)))
(expr_list:REG_DEAD (reg/v:SI 1 r1 [36])
(nil)))
(insn 80 78 83 (set (reg:SI 2 r2 [51])
(and:SI (reg/v:SI 12 ip [34])
(reg/v:SI 3 r3 [37]))) 80 {*arm_andsi3_insn} (insn_list 77
(insn_list 77 (nil)))
(nil))
(insn 83 80 85 (parallel[
(set (reg:CC_NOOV 24 cc)
(compare:CC_NOOV (ior:SI (reg:SI 2 r2 [51])
(reg/v:SI 0 r0 [35]))
(const_int 0 [0x0])))
(set (reg:SI 2 r2 [52])
(ior:SI (reg:SI 2 r2 [51])
(reg/v:SI 0 r0 [35])))
] ) 99 {*iorsi3_compare0} (insn_list 80 (insn_list 80 (nil)))
(expr_list:REG_DEAD (reg/v:SI 0 r0 [35])
(nil)))
(insn 90 113 94 (cond_exec (eq (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (mem:DF (reg/v/f:SI 14 lr [33]) 9)
(reg/v:DF 16 f0 [32]))) 604 {ffssi2+104} (nil)
(nil))
(insn 96 94 104 (cond_exec (eq (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:DF 3 r3 [54])
(reg/v:DF 16 f0 [32]))) 604 {ffssi2+104} (nil)
(nil))
(insn 108 104 110 (cond_exec (eq (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:SI 5 r5 [55])
(and:SI (reg:SI 3 r3 [54])
(const_int -2147483648 [0x80000000])))) 540 {ffssi2+40}
(insn_list 96 (insn_list 96 (nil)))
(nil))
(insn 110 108 112 (cond_exec (eq (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:SI 6 r6 [55])
(reg:SI 2 r2 [52]))) 592 {ffssi2+92} (insn_list:REG_DEP_OUTPUT
108 (nil))
(expr_list:REG_DEAD (reg:SI 2 r2 [52])
(nil)))
(insn 112 110 115 (cond_exec (eq (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg/v:DF 16 f0 [32])
(reg:DF 5 r5 [55]))) 604 {ffssi2+104} (insn_list 108
(insn_list 110 (insn_list:REG_DEP_ANTI 90 (insn_list:REG_DEP_ANTI 96
(nil)))))
(nil))
(insn 136 142 138 (cond_exec (ne (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:SI 4 r4 [58])
(and:SI (not:SI (reg/v:SI 3 r3 [37]))
(reg/v:SI 12 ip [34])))) 544 {ffssi2+44} (nil)
(expr_list:REG_DEAD (reg/v:SI 3 r3 [37])
(expr_list:REG_DEAD (reg/v:SI 12 ip [34])
(nil))))
(insn 138 136 140 (cond_exec (ne (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:SI 5 r5 [58])
(const_int 0 [0x0]))) 592 {ffssi2+92} (insn_list:REG_DEP_OUTPUT
136 (nil))
(nil))
(insn 140 138 144 (cond_exec (ne (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:DF 17 f1 [61])
(reg:DF 4 r4 [58]))) 604 {ffssi2+104} (insn_list 136
(insn_list 138 (nil)))
(expr_list:REG_EQUIV (mem:DF (reg/v/f:SI 14 lr [33]) 9)
(nil)))
(insn 149 144 337 (cond_exec (ne (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:DF 16 f0 [62])
(minus:DF (reg/v:DF 16 f0 [32])
(reg:DF 17 f1 [61])))) 509 {ffssi2+9} (insn_list 140
(insn_list 140 (nil)))
(nil))
(insn 141 337 338 (cond_exec (ne (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (mem:DF (reg/v/f:SI 14 lr [33]) 9)
(reg:DF 17 f1 [61]))) 604 {ffssi2+104} (insn_list 140 (nil))
(expr_list:REG_DEAD (reg:DF 17 f1 [61])
(expr_list:REG_DEAD (reg:CC_NOOV 24 cc)
(nil))))
(jump_insn 349 350 153 (return) -1 (nil)
(nil))
;; End of basic block 2, registers live:
4 [r4] 5 [r5] 6 [r6] 7 [r7] 8 [r8] 13 [sp] 14 [lr] 16 [f0]
After sched 2 the important bit is that after insn 83 (the compare insn),
we have
insn 136: (cond_exec (ne (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:SI 4 r4 [58])
(and:SI (not:SI (reg/v:SI 3 r3 [37]))
(reg/v:SI 12 ip [34]))))
insn 138: (cond_exec (ne (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:SI 5 r5 [58])
(const_int 0 [0x0])))
insn 140: (cond_exec (ne (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:DF 17 f1 [61])
(reg:DF 4 r4 [58])))
insn 96: (cond_exec (eq (reg:CC_NOOV 24 cc)
(const_int 0 [0x0]))
(set (reg:DF 3 r3 [54])
(reg/v:DF 16 f0 [32])))
Now with the first sequence, the compiler thinks that r4 is live at the
start of the block; with the second it doesn't. Now I believe that in
both cases r4 should be dead (since a DFmode set of r3 touches both r3 and
r4 in the EQ arm, and r4 is explicitly set in the NE arm), but the
question is why has the schedule changed the liveness detection? Are we
somehow not handling multi-register sets correctly?
Any ideas?
R.