------- Comment #5 from ubizjak at gmail dot com  2007-08-26 12:55 -------
The problem is in the way ifcvt handles IFs without ELSE blocks. Compiling c
testcase with -O2 -ffast-math (on x86_64 target), we hit check for else_bb in
noce_process_if_block(). We continue into line 2196 of ifcvt.c, where we try to
find a store before condition using:

      prev_insn = prev_nonnote_insn (if_info->cond_earliest);

The problem is, that in gcc-4.3, we have:

;; Pred edge  5 [100.0%]  (fallthru)
;; Pred edge  4 [100.0%]  (fallthru)
(code_label 26 25 27 6 5 "" [0 uses])

(note 27 26 28 6 [bb 6] NOTE_INSN_BASIC_BLOCK)

(insn 28 27 32 6 pr33181.c:14 (set (mem:SI (reg/v/f:DI 59 [ stat ]) [2 S4 A32])
        (reg:SI 58 [ iftmp.0 ])) 47 {*movsi_1} (expr_list:REG_DEAD (reg/v/f:DI
59 [ stat ])
        (expr_list:REG_DEAD (reg:SI 58 [ iftmp.0 ])
            (nil))))
;; End of basic block 6 -> ( 9)
;; lr  out       6 [bp] 7 [sp] 16 [argp] 20 [frame]
;; live  out     6 [bp] 7 [sp] 16 [argp] 20 [frame]


;; Succ edge  9 [100.0%]  (fallthru)

;; Start of basic block ( 2) -> 7
;; bb 7 artificial_defs: { }
;; bb 7 artificial_uses: { u35(6){ }u36(7){ }u37(16){ }u38(20){ }}
;; lr  in        6 [bp] 7 [sp] 16 [argp] 20 [frame] 59 60 61
;; lr  use       6 [bp] 7 [sp] 16 [argp] 20 [frame] 60 61
;; lr  def       17 [flags]
;; live  in      6 [bp] 7 [sp] 16 [argp] 20 [frame] 59 60 61
;; live  gen     17 [flags]
;; live  kill

;; Pred edge  2 [50.0%]  (fallthru)
(note 32 28 33 7 [bb 7] NOTE_INSN_BASIC_BLOCK)

(insn 33 32 34 7 pr33181.c:15 (set (reg:CCFP 17 flags)
        (compare:CCFP (reg/v:DF 60 [ newUpper ])
            (reg/v:DF 61 [ lower ]))) 35 {*cmpfp_i_sse} (expr_list:REG_DEAD
(reg/v:DF 61 [ lower ])
        (expr_list:REG_DEAD (reg/v:DF 60 [ newUpper ])
            (nil))))

So, previous non-note insn from (insn 33) is (insn 28)(!!) in a totally
unrelated BB, leading to all sort of strange things.

For comparison, in gcc-4.1 we have a lot cleaner sequence:

--cut here--
;; Start of basic block 5, registers live: (nil)
(code_label 43 42 44 5 2 "" [1 uses])

(note 44 43 46 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(insn 46 44 47 5 (set (reg:CCFP 17 flags)
        (compare:CCFP (reg/v:DF 60 [ newUpper ])
            (reg/v:DF 61 [ lower ]))) 28 {*cmpfp_i_sse} (nil)
    (nil))

(jump_insn 47 46 52 5 (set (pc)
        (if_then_else (ltgt (reg:CCFP 17 flags)
                (const_int 0 [0x0]))
            (label_ref:DI 62)
            (pc))) 531 {*jcc_1} (nil)
    (expr_list:REG_BR_PROB (const_int 3300 [0xce4])
        (nil)))
;; End of basic block 5, registers live:
 (nil)

;; Start of basic block 6, registers live: (nil)
(note 52 47 54 6 [bb 6] NOTE_INSN_BASIC_BLOCK)

(insn 54 52 57 6 (set (mem:SI (reg/v/f:DI 59 [ stat ]) [2 S4 A32])
        (const_int -4 [0xfffffffffffffffc])) 40 {*movsi_1} (nil)
    (nil))
;; End of basic block 6, registers live:
 (nil)

(note 57 54 62 NOTE_INSN_FUNCTION_END)

;; Start of basic block 7, registers live: (nil)
(code_label 62 57 71 7 12 "" [2 uses])

(note 71 62 0 7 [bb 7] NOTE_INSN_BASIC_BLOCK)
;; End of basic block 7, registers live:
 (nil)
--cut here--

And previous non-note insn of the condition is (code label 43) that correctly
blocks cmove conversion.

Perhaps Jan has an advice on prev_nonnote_insn() usage in
noce_process_if_block().


-- 

ubizjak at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hubicka at gcc dot gnu dot
                   |                            |org


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

Reply via email to