If the OP_COMPUTEDGOTO's source pseudo is defined by a single OP_SETVAL/EXPR_LABEL, then the corresponding basic block is the only possible destination and the computed goto can then be simplified into a simple branch. So, convert such computed goto into a simple OP_BR which may then participate in other flow simplifications. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- simplify.c | 30 ++++++++++++++++++++++++++++++ validation/optim/cgoto01.c | 1 - 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/simplify.c b/simplify.c index e58fb6cf3941..132d408f59f1 100644 --- a/simplify.c +++ b/simplify.c @@ -2112,6 +2112,34 @@ found: return REPEAT_CSE; } +static int simplify_cgoto(struct instruction *insn) +{ + struct basic_block *target, *bb = insn->bb; + struct instruction *def; + struct multijmp *jmp; + + switch (DEF_OPCODE(def, insn->src)) { + case OP_SETVAL: + if (def->val->type != EXPR_LABEL) + break; + target = def->val->symbol->bb_target; + if (!target->ep) + return 0; + FOR_EACH_PTR(insn->multijmp_list, jmp) { + if (jmp->target == target) + continue; + remove_bb_from_list(&jmp->target->parents, bb, 1); + remove_bb_from_list(&bb->children, jmp->target, 1); + MARK_CURRENT_DELETED(jmp); + } END_FOR_EACH_PTR(jmp); + kill_use(&insn->src); + insn->opcode = OP_BR; + insn->bb_true = target; + return REPEAT_CSE|REPEAT_CFG_CLEANUP; + } + return 0; +} + int simplify_instruction(struct instruction *insn) { unsigned flags; @@ -2190,6 +2218,8 @@ int simplify_instruction(struct instruction *insn) return simplify_branch(insn); case OP_SWITCH: return simplify_switch(insn); + case OP_COMPUTEDGOTO: + return simplify_cgoto(insn); case OP_RANGE: return simplify_range(insn); case OP_FADD: diff --git a/validation/optim/cgoto01.c b/validation/optim/cgoto01.c index 350c6cd99f08..94b2c2c429db 100644 --- a/validation/optim/cgoto01.c +++ b/validation/optim/cgoto01.c @@ -16,7 +16,6 @@ L2: abort(); /* * check-name: cgoto01 * check-command: test-linearize -Wno-decl $file - * check-known-to-fail * * check-output-ignore * check-output-excludes: set\\. -- 2.29.2