------- 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