Enhance fold sibcall pass to fold sibcall targets into jump table by turning:
foo: .cfi_startproc cmpl $4, %edi ja .L1 movl %edi, %edi jmp *.L4(,%rdi,8) .section .rodata .L4: .quad .L8 .quad .L7 .quad .L6 .quad .L5 .quad .L3 .text .L5: jmp bar3 .L3: jmp bar4 .L8: jmp bar0 .L7: jmp bar1 .L6: jmp bar2 .L1: ret .cfi_endproc into: foo: .cfi_startproc cmpl $4, %edi ja .L1 movl %edi, %edi jmp *.L4(,%rdi,8) .section .rodata .L4: .quad bar0 .quad bar1 .quad bar2 .quad bar3 .quad bar4 .text .L1: ret .cfi_endproc After basic block reordering pass, jump tables look like: (jump_table_data 16 15 17 (addr_vec:DI [ (label_ref:DI 18) (label_ref:DI 22) (label_ref:DI 26) (label_ref:DI 30) (label_ref:DI 34) ])) ... (code_label 30 17 31 4 5 (nil) [1 uses]) (note 31 30 32 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (call_insn/j 32 31 33 4 (call (mem:QI (symbol_ref:DI ("bar3") [flags 0x41] <function_decl 0x7f21be3c0e00 bar3>) [0 bar3 S1 A8]) (const_int 0 [0])) "j.c":15:13 1469 {sibcall_di} (expr_list:REG_CALL_DECL (symbol_ref:DI ("bar3") [flags 0x41] <function_decl 0x7f21be3c0e00 bar3>) (nil)) (nil)) If the jump table entry points to a target basic block with only a direct sibcall, change the entry to point to the sibcall target and decrement the target basic block entry label use count. If the target basic block isn't kept for JUMP_LABEL of the conditional tailcall, delete it if its entry label use count is 0. Update create_trace_edges to skip symbol reference in jump table and update final_scan_insn_1 to support symbol reference in jump table. gcc/ PR target/14721 * dwarf2cfi.cc (create_trace_edges): Skip symbol reference in jump table. * final.cc (final_scan_insn_1): Support symbol reference in jump table. * config/i386/i386-features.cc (jump_table_label_to_basic_block): New. (fold_sibcall): Fold the sibcall targets into jump table. gcc/testsuite/ PR target/14721 * gcc.target/i386/pr14721-1a.c: New. * gcc.target/i386/pr14721-1b.c: Likewise. * gcc.target/i386/pr14721-1c.c: Likewise. * gcc.target/i386/pr14721-2c.c: Likewise. * gcc.target/i386/pr14721-2b.c: Likewise. * gcc.target/i386/pr14721-2c.c: Likewise. * gcc.target/i386/pr14721-3c.c: Likewise. * gcc.target/i386/pr14721-3b.c: Likewise. * gcc.target/i386/pr14721-3c.c: Likewise. Signed-off-by: H.J. Lu <hjl.to...@gmail.com> --- gcc/config/i386/i386-features.cc | 70 +++++++++++++++++++++- gcc/dwarf2cfi.cc | 7 ++- gcc/final.cc | 22 ++++++- gcc/testsuite/gcc.target/i386/pr14721-1a.c | 54 +++++++++++++++++ gcc/testsuite/gcc.target/i386/pr14721-1b.c | 37 ++++++++++++ gcc/testsuite/gcc.target/i386/pr14721-1c.c | 37 ++++++++++++ gcc/testsuite/gcc.target/i386/pr14721-2a.c | 58 ++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr14721-2b.c | 41 +++++++++++++ gcc/testsuite/gcc.target/i386/pr14721-2c.c | 43 +++++++++++++ gcc/testsuite/gcc.target/i386/pr14721-3a.c | 56 +++++++++++++++++ gcc/testsuite/gcc.target/i386/pr14721-3b.c | 40 +++++++++++++ gcc/testsuite/gcc.target/i386/pr14721-3c.c | 39 ++++++++++++ 12 files changed, 499 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-1a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-1b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-1c.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-2a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-2b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-2c.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-3a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-3b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-3c.c diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index bb1e428bb1b..e89c8324f34 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -3328,6 +3328,22 @@ sibcall_only_bb (basic_block bb, bitmap sibcall_bbs) return nullptr; } +/* Return the sibcall target if the basic block referenced by LABEL only + has a direct sibcall. */ + +static rtx +jump_table_label_to_basic_block (rtx label, bitmap sibcall_bbs) +{ + label = XEXP (label, 0); + basic_block bb = BLOCK_FOR_INSN (label); + rtx target = sibcall_only_bb (bb, sibcall_bbs); + /* Decrement the label use count if jump table entry will use the + sibcall directly. */ + if (target) + LABEL_NUSES (label) -= 1; + return target; +} + /* Fold direct sibcall. */ static unsigned int @@ -3337,11 +3353,13 @@ fold_sibcall (void) bitmap_obstack_initialize (NULL); bitmap jcc_sibcall_bbs = BITMAP_ALLOC (NULL); + bitmap table_sibcall_bbs = BITMAP_ALLOC (NULL); unsigned int todo = 0; basic_block bb; rtx_insn *insn; bool jcc_sibcall = false; + bool table_sibcall = false; FOR_EACH_BB_FN (bb, cfun) { @@ -3350,10 +3368,11 @@ fold_sibcall (void) if (!JUMP_P (insn)) continue; + rtx label = JUMP_LABEL (insn); + rtx sibcall_target; + if (INSN_CODE (insn) == CODE_FOR_jcc) { - rtx label = JUMP_LABEL (insn); - rtx sibcall_target; edge branch_edge = BRANCH_EDGE (bb); basic_block branch_bb = branch_edge->dest; sibcall_target = sibcall_only_bb (branch_bb, @@ -3373,6 +3392,33 @@ fold_sibcall (void) jcc_sibcall = true; } } + else if (label && !ANY_RETURN_P (label)) + { + /* Check if it is a jump table with addresses. */ + rtx_insn *target = as_a<rtx_insn *> (label); + rtx_insn *table = next_insn (target); + if (!table + || !JUMP_TABLE_DATA_P (table) + || GET_CODE (PATTERN (table)) != ADDR_VEC) + continue; + + rtx body = PATTERN (table); + unsigned int len = XVECLEN (body, 0); + for (unsigned int i = 0; i < len; i++) + { + rtx elt = XVECEXP (body, 0, i); + sibcall_target + = jump_table_label_to_basic_block (elt, + table_sibcall_bbs); + /* Fold the sibcall target by changing the jump table + entry to the sibcall target. */ + if (sibcall_target) + { + XVECEXP (body, 0, i) = sibcall_target; + table_sibcall = true; + } + } + } } } @@ -3440,6 +3486,26 @@ fold_sibcall (void) } } + if (table_sibcall) + { + bitmap_iterator bi; + unsigned id; + EXECUTE_IF_SET_IN_BITMAP (table_sibcall_bbs, 0, id, bi) + { + /* Check if this basic block should be kept for JUMP_LABEL of + the conditional tailcall. */ + if (jcc_sibcall_bbs && bitmap_bit_p (jcc_sibcall_bbs, id)) + continue; + bb = BASIC_BLOCK_FOR_FN (cfun, id); + insn = BB_HEAD (bb); + gcc_assert (LABEL_P (insn)); + /* Delete the basic block if its entry label is unused now. */ + if (LABEL_NUSES (insn) == 0) + delete_basic_block (bb); + } + } + + BITMAP_FREE (table_sibcall_bbs); BITMAP_FREE (jcc_sibcall_bbs); bitmap_obstack_release (NULL); diff --git a/gcc/dwarf2cfi.cc b/gcc/dwarf2cfi.cc index a5353d39e7e..e80b2061453 100644 --- a/gcc/dwarf2cfi.cc +++ b/gcc/dwarf2cfi.cc @@ -2657,7 +2657,12 @@ create_trace_edges (rtx_insn *insn) n = GET_NUM_ELEM (vec); for (i = 0; i < n; ++i) { - rtx_insn *lab = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, i), 0)); + rtx l = RTVEC_ELT (vec, i); + /* Skip symbol reference. */ + if (SYMBOL_REF_P (l)) + continue; + l = XEXP (l, 0); + rtx_insn *lab = as_a <rtx_insn *> (l); maybe_record_trace_start (lab, insn); } diff --git a/gcc/final.cc b/gcc/final.cc index 5fb44433fb8..602bfb09005 100644 --- a/gcc/final.cc +++ b/gcc/final.cc @@ -2528,13 +2528,31 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, } #else vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC); + const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, true); + gcc_assert (asm_op != NULL); for (idx = 0; idx < vlen; idx++) { if (GET_CODE (body) == ADDR_VEC) { #ifdef ASM_OUTPUT_ADDR_VEC_ELT - ASM_OUTPUT_ADDR_VEC_ELT - (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0))); + rtx l = XVECEXP (body, 0, idx); + if (SYMBOL_REF_P (l)) + { + fprintf (file, "%s", asm_op); + assemble_external (SYMBOL_REF_DECL (l)); +#ifdef ASM_OUTPUT_SYMBOL_REF + ASM_OUTPUT_SYMBOL_REF (file, l); +#else + assemble_name (file, XSTR (l, 0)); +#endif + putc ('\n', file); + } + else + { + l = XEXP (l, 0); + ASM_OUTPUT_ADDR_VEC_ELT + (file, CODE_LABEL_NUMBER (l)); + } #else gcc_unreachable (); #endif diff --git a/gcc/testsuite/gcc.target/i386/pr14721-1a.c b/gcc/testsuite/gcc.target/i386/pr14721-1a.c new file mode 100644 index 00000000000..0ebd16554b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-1a.c @@ -0,0 +1,54 @@ +/* { dg-do compile { target { *-*-linux* && lp64 } } } */ +/* { dg-options "-O2 -fno-pic -fplt" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** cmpl \$4, %edi +** ja .L1 +** movl %edi, %edi +** jmp \*.L4\(,%rdi,8\) +** .section .rodata +**... +**.L4: +** .quad bar0 +** .quad bar1 +** .quad bar2 +** .quad bar3 +** .quad bar4 +**... +** .text +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +extern void bar0 (void); +extern void bar1 (void); +extern void bar2 (void); +extern void bar3 (void); +extern void bar4 (void); + +void +foo (int i) +{ + switch (i) + { + case 0: bar0 (); break; + case 1: bar1 (); break; + case 2: bar2 (); break; + case 3: bar3 (); break; + case 4: bar4 (); break; + } +} + +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar0" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar1" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar2" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar3" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar4" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr14721-1b.c b/gcc/testsuite/gcc.target/i386/pr14721-1b.c new file mode 100644 index 00000000000..d194a332221 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-1b.c @@ -0,0 +1,37 @@ +/* { dg-do compile { target { *-*-linux* && ia32 } } } */ +/* { dg-options "-O2 -fno-pic -fplt" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movl 4\(%esp\), %eax +** cmpl \$4, %eax +** ja .L1 +** jmp \*.L4\(,%eax,4\) +** .section .rodata +**... +**.L4: +** .long bar0 +** .long bar1 +** .long bar2 +** .long bar3 +** .long bar4 +**... +** .text +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +#include "pr14721-1a.c" + +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar0" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar1" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar2" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar3" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar4" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr14721-1c.c b/gcc/testsuite/gcc.target/i386/pr14721-1c.c new file mode 100644 index 00000000000..1a9b137d5a0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-1c.c @@ -0,0 +1,37 @@ +/* { dg-do compile { target { *-*-linux* && maybe_x32 } } } */ +/* { dg-options "-O2 -fno-pic -fplt -mx32" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** cmpl \$4, %edi +** ja .L1 +** movl .L4\(,%edi,4\), %eax +** jmp \*%rax +** .section .rodata +**... +**.L4: +** .long bar0 +** .long bar1 +** .long bar2 +** .long bar3 +** .long bar4 +**... +** .text +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +#include "pr14721-1a.c" + +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar0" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar1" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar2" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar3" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar4" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr14721-2a.c b/gcc/testsuite/gcc.target/i386/pr14721-2a.c new file mode 100644 index 00000000000..a5a0d6c147a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-2a.c @@ -0,0 +1,58 @@ +/* { dg-do compile { target { *-*-linux* && lp64 } } } */ +/* { dg-options "-O2 -fno-pic -fplt" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** cmpl \$4, %edi +** ja .L1 +** movl %edi, %edi +** jmp \*.L4\(,%rdi,8\) +** .section .rodata +**... +**.L4: +** .quad bar0 +** .quad .L7 +** .quad .L6 +** .quad bar3 +** .quad bar4 +**... +** .text +**... +**.L7: +** jmp \*bar1\(%rip\) +**... +**.L6: +** jmp \*bar2\(%rip\) +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +extern void bar0 (void); +extern void (*bar1) (void); +extern void (*bar2) (void); +extern void bar3 (void); +extern void bar4 (void); + +void +foo (int i) +{ + switch (i) + { + case 0: bar0 (); break; + case 1: bar1 (); break; + case 2: bar2 (); break; + case 3: bar3 (); break; + case 4: bar4 (); break; + } +} + +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar0" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar3" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar4" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr14721-2b.c b/gcc/testsuite/gcc.target/i386/pr14721-2b.c new file mode 100644 index 00000000000..9edc23a063d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-2b.c @@ -0,0 +1,41 @@ +/* { dg-do compile { target { *-*-linux* && ia32 } } } */ +/* { dg-options "-O2 -fno-pic -fplt" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movl 4\(%esp\), %eax +** cmpl \$4, %eax +** ja .L1 +** jmp \*.L4\(,%eax,4\) +** .section .rodata +**... +**.L4: +** .long bar0 +** .long .L7 +** .long .L6 +** .long bar3 +** .long bar4 +**... +** .text +**... +**.L7: +** jmp \*bar1 +**... +**.L6: +** jmp \*bar2 +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +#include "pr14721-2a.c" + +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar0" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar3" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar4" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr14721-2c.c b/gcc/testsuite/gcc.target/i386/pr14721-2c.c new file mode 100644 index 00000000000..c0d8d7b23cb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-2c.c @@ -0,0 +1,43 @@ +/* { dg-do compile { target { *-*-linux* && maybe_x32 } } } */ +/* { dg-options "-O2 -fno-pic -fplt -mx32" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** cmpl \$4, %edi +** ja .L1 +** movl .L4\(,%edi,4\), %eax +** jmp \*%rax +** .section .rodata +**... +**.L4: +** .long bar0 +** .long .L7 +** .long .L6 +** .long bar3 +** .long bar4 +**... +** .text +**... +**.L7: +** movl bar1\(%rip\), %eax +** jmp \*%rax +**... +**.L6: +** movl bar2\(%rip\), %eax +** jmp \*%rax +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +#include "pr14721-2a.c" + +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar0" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar3" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar4" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr14721-3a.c b/gcc/testsuite/gcc.target/i386/pr14721-3a.c new file mode 100644 index 00000000000..78e073723eb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-3a.c @@ -0,0 +1,56 @@ +/* { dg-do compile { target { *-*-linux* && lp64 } } } */ +/* { dg-options "-O2 -fno-pic -fplt" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** testl %esi, %esi +** jne bar0 +** cmpl \$4, %edi +** ja .L1 +** movl %edi, %edi +** jmp \*.L5\(,%rdi,8\) +** .section .rodata +**... +**.L5: +** .quad bar0 +** .quad bar1 +** .quad bar2 +** .quad bar3 +** .quad bar4 +**... +** .text +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +extern void bar0 (void); +extern void bar1 (void); +extern void bar2 (void); +extern void bar3 (void); +extern void bar4 (void); + +void +foo (int i, int j) +{ + if (j) + { + bar0 (); + return; + } + + switch (i) + { + case 0: bar0 (); break; + case 1: bar1 (); break; + case 2: bar2 (); break; + case 3: bar3 (); break; + case 4: bar4 (); break; + } +} diff --git a/gcc/testsuite/gcc.target/i386/pr14721-3b.c b/gcc/testsuite/gcc.target/i386/pr14721-3b.c new file mode 100644 index 00000000000..3870e963e4b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-3b.c @@ -0,0 +1,40 @@ +/* { dg-do compile { target { *-*-linux* && ia32 } } } */ +/* { dg-options "-O2 -fno-pic -fplt" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movl 8\(%esp\), %edx +** movl 4\(%esp\), %eax +** testl %edx, %edx +** jne bar0 +** cmpl \$4, %eax +** ja .L1 +** jmp \*.L5\(,%eax,4\) +** .section .rodata +**... +**.L5: +** .long bar0 +** .long bar1 +** .long bar2 +** .long bar3 +** .long bar4 +**... +** .text +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +#include "pr14721-3a.c" + +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar0" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar1" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar2" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar3" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar4" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr14721-3c.c b/gcc/testsuite/gcc.target/i386/pr14721-3c.c new file mode 100644 index 00000000000..fa763099bd3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr14721-3c.c @@ -0,0 +1,39 @@ +/* { dg-do compile { target { *-*-linux* && maybe_x32 } } } */ +/* { dg-options "-O2 -fno-pic -fplt -mx32" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** testl %esi, %esi +** jne bar0 +** cmpl \$4, %edi +** ja .L1 +** movl .L5\(,%edi,4\), %eax +** jmp \*%rax +** .section .rodata +**... +**.L5: +** .long bar0 +** .long bar1 +** .long bar2 +** .long bar3 +** .long bar4 +**... +** .text +**... +**.L1: +** ret +** .cfi_endproc +**... +*/ + +#include "pr14721-3a.c" + +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar0" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar1" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar2" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar3" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]*bar4" } } */ -- 2.48.1