On Wed, Jul 29, 2026 at 9:49 AM H.J. Lu <[email protected]> wrote:
>
> x86 conditional branch (jcc) target can be either a label or a symbol.
> Add a pass to fold tail call with jcc by turning:
>
> jcc .L6
> ...
> .L6:
> jmp tailcall
>
> into:
>
> jcc tailcall
>
> Immediately before the pass which turning REG_EH_REGION notes back into
> NOTE_INSN_EH_REGION notes, conditional branches look like
>
> (jump_insn 7 6 14 2 (set (pc)
> (if_then_else (eq (reg:CCZ 17 flags)
> (const_int 0 [0]))
> (label_ref:DI 23)
> (pc))) "x.c":8:5 1458 {jcc}
> (expr_list:REG_DEAD (reg:CCZ 17 flags)
> (int_list:REG_BR_PROB 217325348 (nil)))
> ...
> (code_label 23 20 8 4 4 (nil) [1 uses])
> (note 8 23 9 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
> (call_insn/j 9 8 10 4 (call (mem:QI (symbol_ref:DI ("bar") [flags 0x41]
> <functi
> on_decl 0x7f4cff3c0b00 bar>) [0 bar S1 A8])
> (const_int 0 [0])) "x.c":8:14 discrim 1 1469 {sibcall_di}
> (expr_list:REG_CALL_DECL (symbol_ref:DI ("bar") [flags 0x41]
> <function_dec
> l 0x7f4cff3c0b00 bar>)
> (nil))
> (nil))
>
> Searching backward from exit basic blocks with only sibcalls, check the
> last instruction in each predecessor. If the last instruction is a
> conditional jump and its target is the exit block, change the conditional
> jump target to the sibcall target, decrement the destination basic block
> entry label use count, redirect the edge to the exit basic block and call
> delete_unreachable_blocks to delete the unreachable basic blocks. Repeat
> it until there is no conditional jump to update.
I think this should use cond_exec infrastructure, where ifcvt rewrites
conditional jump + sibcall to a RTX like:
(cond_exec
(match_operator 0 "ix86_comparison_operator" [(reg:CC FLAGS_REG)
(const_int 0)])
(call (mem:QI (match_operand:W 1 "constant_call_address_operand"))
(match_operand 2)))
It looks that ifcvt is able to do this transformation, since
ifcvt.cc's cond_exec_process_insns, the core loop that wraps an insn's
pattern in COND_EXEC, explicitly asserts NONJUMP_INSN_P (insn) ||
CALL_P (insn).
Looking at arm.md, its call instructions use %? predicate, but they
don't set "predicated" attribute for some reason.
Please see chapter 18.21 Conditional Execution in GCC internals.
Uros.