https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118012
--- Comment #14 from Georg-Johann Lay <gjl at gcc dot gnu.org> --- (In reply to Richard Biener from comment #13) > On RTL we do target costing for if-conversion sequences, PHI-OPT doesn't ...and... > For specific cases improving RTL expansion is also possible Which doesn't work well. For example: * A MULT_EXPR may be expanded as a libgcc call, and RTL lowering sees a call, not a genuine multiplication. * Costing like in, say, expr.cc::expand_expr_real_2[MULR_EXPR] only queries mul_costs, hence the backend doesn't see that it's just a bit test. The only place hat tells the truth is insn combine that querires (xor:hi (mult:hi (and:hi (reg:HI, 1))), but to get an insn like ;; Map ;; $0 = (($1 AND 1) MULT $2) o $3 ;; to ;; $0 = $3 ;; if ($1.0 == 0) ;; goto L ;; $0 o= $2 ;; L:; (define_insn_and_split "*mul.and1-to-skip.<QISI:mode>" [(set (match_operand:QISI 0 "register_operand") (pixop:QISI (mult:QISI (and:QISI (match_operand:QISI2 1 "register_operand") (const_int 1)) (match_operand:QISI 2 "nonmemory_operand")) (match_operand:QISI 3 "register_operand")))] "avr_pr118012_p && ! reload_completed" ... requires intermediate pattens because combine only looks so deep. * Costs may lead the wrong way, for example a NEG expanded inline is more expensive than a __mulsi3l libgcc call when optimizing for size. But still you don't want a full fledged multiplication to (effectively) perform a bit test. So no, just do RTL costing won't solve the problem completely IMO. Apart from that, at RTL level you only see the operand to the arithmetic. For example, in if (b & 1) c ^= a; you don't see the "c ^= " part. You only see a "op = a * bit_extract(b,0)" which could be performed as if (b = 1) op = a; else op = 0; But that is still more exoensive in code, execution time and register pressure than the original code.