For
int test1(int x)
{
if (x & 2)
x |= 2;
return x;
}
The final generated a-test.c.267t.optimized is as follows:
<bb 2> [local count: 1073741824]:
_1 = x_3(D) & 2;
if (_1 != 0)
goto <bb 3>; [50.00%]
else
goto <bb 4>; [50.00%]
<bb 3> [local count: 536870913]:
x_4 = x_3(D) | 2;
<bb 4> [local count: 1073741824]:
# x_2 = PHI <x_3(D)(2), x_4(3)>
return x_2;
During optimization of the noce_try_bitop function, if_info->test_bb is as
follows:
(note 4 0 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(insn 2 4 3 2 (set (reg/v:SI 84 [ x ])
(reg:SI 5 di [ x ])) "test.c":5:1 81 {*movsi_internal}
(expr_list:REG_DEAD (reg:SI 5 di [ x ])
(nil)))
(note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)
(insn 6 3 7 2 (parallel [
(set (reg:SI 85)
(and:SI (reg/v:SI 84 [ x ])
(const_int 2 [0x2])))
(clobber (reg:CC 17 flags))
]) "test.c":6:9 533 {*andsi_1}
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil)))
(insn 7 6 8 2 (set (reg:CCZ 17 flags)
(compare:CCZ (reg:SI 85)
(const_int 0 [0]))) "test.c":6:6 7 {*cmpsi_ccno_1}
(expr_list:REG_DEAD (reg:SI 85)
(nil)))
(jump_insn 8 7 9 2 (set (pc)
(if_then_else (eq (reg:CCZ 17 flags)
(const_int 0 [0]))
(label_ref:DI 11)
(pc))) "test.c":6:6 891 {*jcc}
(expr_list:REG_DEAD (reg:CCZ 17 flags)
(int_list:REG_BR_PROB 536870916 (nil)))
-> 11)
if_info->cond is as follows:
(eq (reg:SI 85)
(const_int 0 [0]))
When evaluating the following two lines, GET_CODE(cond) is REG rather than
ZERO_EXTRACT, because XEXP(if_info->cond, 0) is reg:SI, not (and:SI
(reg/v:SI 84 [ x ]) (const_int 2 [0x2])).
Thus, the optimization that should have occurred here has failed.
cond = XEXP (cond, 0);
if (GET_CODE (cond) == ZERO_EXTRACT)
If I want to re-enable the optimization here, should I locate the
instruction where the register XEXP (if_info->cond, 0) was last set, i.e.,
(and:SI (reg/v:SI 84 [ x ]) (const_int 2 [0x2]), and then perform the
optimization based on that instruction?