http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59660
--- Comment #8 from Jan Hubicka <hubicka at ucw dot cz> --- Fe produces: <cond_expr 0x7ffff7004840 type <integer_type 0x7ffff6ede690 int public SI size <integer_cst 0x7ffff6ee03c0 constant 32> unit size <integer_cst 0x7ffff6ee03e0 constant 4> align 32 symtab 0 alias set -1 canonical type 0x7ffff6ede690 precision 32 min <integer_cst 0x7ffff6ee0360 -2147483648> max <integer_cst 0x7ffff6ee0380 2147483647> pointer_to_this <pointer_type 0x7ffff6eea738>> side-effects arg 0 <truth_orif_expr 0x7ffff6fe5a78 type <boolean_type 0x7ffff6edebd0 _Bool public unsigned QI size <integer_cst 0x7ffff6ee0200 constant 8> unit size <integer_cst 0x7ffff6ee0220 constant 1> align 8 symtab 0 alias set -1 canonical type 0x7ffff6edebd0 precision 1 min <integer_cst 0x7ffff6ee05c0 0> max <integer_cst 0x7ffff6ee0600 1>> side-effects arg 0 <eq_expr 0x7ffff6fe5a50 type <boolean_type 0x7ffff6edebd0 _Bool> arg 0 <parm_decl 0x7ffff7006000 n> arg 1 <parm_decl 0x7ffff7006080 m> /home/jh/t.c:5:13> arg 1 <call_expr 0x7ffff7009000 type <boolean_type 0x7ffff6edebd0 _Bool> side-effects fn <addr_expr 0x7ffff6ff4740 type <pointer_type 0x7ffff7008000> constant arg 0 <function_decl 0x7ffff6fea600 m_is_less_than_n> /home/jh/t.c:5:37> arg 0 <plus_expr 0x7ffff6fe5988 type <integer_type 0x7ffff6ede690 int> arg 0 <parm_decl 0x7ffff7006000 n> arg 1 <integer_cst 0x7ffff6ee0680 constant -1> /home/jh/t.c:5:39> arg 1 <parm_decl 0x7ffff7006080 m> /home/jh/t.c:5:37> /home/jh/t.c:5:17> arg 1 <integer_cst 0x7ffff6ee0640 type <integer_type 0x7ffff6ede690 int> constant 1> arg 2 <integer_cst 0x7ffff6ee0620 type <integer_type 0x7ffff6ede690 int> constant 0> /home/jh/t.c:5:17> The sequence of jumps is produced in shortcut_cond_r an it seems we do this silly thing for every conditional where at least one of two has side effect. The code produces basically if (cond1) goto true_label if (cond2) goto true_label else goto false_laebl true_label: tmp=1 goto jump_around fasle_label; tmp=2 jump_around: It would make more sense to do if (cond1) goto true_label tmp = cond2; goto jump_around true_label tmp = true jump_around: It seems it would be always a win. I will see if my gimplifier-fu is on par to hack this in.