https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107642
Bug ID: 107642 Summary: LOGICAL_OP_NON_SHORT_CIRCUIT vs BRANCH_COST confusion Product: gcc Version: 13.0 Status: UNCONFIRMED Keywords: documentation, internal-improvement, missed-optimization Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: pinskia at gcc dot gnu.org Target Milestone: --- LOGICAL_OP_NON_SHORT_CIRCUIT is defined as: @defmac LOGICAL_OP_NON_SHORT_CIRCUIT Define this macro if a non-short-circuit operation produced by @samp{fold_range_test ()} is optimal. This macro defaults to true if @code{BRANCH_COST} is greater than or equal to the value 2. @end defmac Some targets define it to 0 or something else: apinski@xeond:~/src/upstream-gcc-git/gcc/gcc/config$ git grep LOGICAL_OP_NON_SHORT_CIRCUIT */*.h arc/arc.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT \ arm/arm.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT \ csky/csky.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT \ loongarch/loongarch.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 mips/mips.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 msp430/msp430.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 nds32/nds32.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 pru/pru.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 riscv/riscv.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 rs6000/rs6000.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 visium/visium.h:#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 arc.h: #define LOGICAL_OP_NON_SHORT_CIRCUIT \ (BRANCH_COST (optimize_function_for_speed_p (cfun), \ false) > 9) arm.h: #define LOGICAL_OP_NON_SHORT_CIRCUIT \ ((optimize_size) \ ? (TARGET_THUMB ? false : true) \ : TARGET_THUMB ? static_cast<bool> (current_tune->logical_op_non_short_circuit_thumb) \ : static_cast<bool> (current_tune->logical_op_non_short_circuit_arm)) csky.h (which is the default it seems): #define LOGICAL_OP_NON_SHORT_CIRCUIT \ (csky_default_logical_op_non_short_circuit ()) ... bool csky_default_logical_op_non_short_circuit (void) { return BRANCH_COST (optimize_function_for_speed_p (cfun), false) >= 2; } LOGICAL_OP_NON_SHORT_CIRCUIT is used in many few places than fold_range_test these days too. fold-const.cc:#ifndef LOGICAL_OP_NON_SHORT_CIRCUIT fold-const.cc:#define LOGICAL_OP_NON_SHORT_CIRCUIT \ fold-const.cc: bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT; fold-const.cc: bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT; tree-ssa-ifcombine.cc:#ifndef LOGICAL_OP_NON_SHORT_CIRCUIT tree-ssa-ifcombine.cc:#define LOGICAL_OP_NON_SHORT_CIRCUIT \ tree-ssa-ifcombine.cc: bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT; fold_truth_andor in fold-const.cc ifcombine_ifandif in tree-ssa-ifcombine.cc What LOGICAL_OP_NON_SHORT_CIRCUIT is trying to say is that expansion (from gimple to RTL) of things like `a & b` (where a and b are bools) is cheaper than expanding out using jumps. Note this is not exactly true as there is code which does that again in dojump.cc: /* High branch cost, expand as the bitwise OR of the conditions. Do the same if the RHS has side effects, because we're effectively turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR. */ if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))