On Thu, Feb 14, 2019 at 08:13:32PM -0800, H.J. Lu wrote: > NOTE_INSN_DELETED_LABEL is used to mark what used to be a 'code_label', > but was not used for other purposes than taking its address and was > transformed to mark that no code jumps to it. NOTE_INSN_DELETED_LABEL > is generated only in 3 places: > > 1. When delete_insn sees an unused label which is an explicit label in > the input source code or its address is taken, it turns the label into > a NOTE_INSN_DELETED_LABEL note. > 2. When rtl_tidy_fallthru_edge deletes a tablejump, it turns the > tablejump into a NOTE_INSN_DELETED_LABEL note. > 3. ix86_init_large_pic_reg creats a NOTE_INSN_DELETED_LABEL note, .L2, > to initialize large model PIC register: > > L2: > movabsq $_GLOBAL_OFFSET_TABLE_-.L2, %r11 > leaq .L2(%rip), %rax > movabsq $val@GOT, %rdx > addq %r11, %rax > > Among of them, ENDBR is needed only when the label address is taken. > rest_of_insert_endbranch has > > if ((LABEL_P (insn) && LABEL_PRESERVE_P (insn)) > || (NOTE_P (insn) > && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)) > /* TODO. Check /s bit also. */ > { > cet_eb = gen_nop_endbr (); > emit_insn_after (cet_eb, insn); > continue; > } > > For NOTE_INSN_DELETED_LABEL, we should check if forced_labels to see > if its address is taken. Also ix86_init_large_pic_reg shouldn't set > LABEL_PRESERVE_P (in_struct) since NOTE_INSN_DELETED_LABEL is suffcient > to keep the label. > > gcc/ > > PR target/89355 > * config/i386/i386.c (rest_of_insert_endbranch): Check > forced_labels to see if the address of NOTE_INSN_DELETED_LABEL > is taken. > (ix86_init_large_pic_reg): Don't set LABEL_PRESERVE_P. >
Here is the updated patch. We should check LABEL_PRESERVE_P on NOTE_INSN_DELETED_LABEL to see if its address is taken. OK for trunk? Thanks. H.J. --- NOTE_INSN_DELETED_LABEL is used to mark what used to be a 'code_label', but was not used for other purposes than taking its address and was transformed to mark that no code jumps to it. Since LABEL_PRESERVE_P is true only if the label address was taken, check LABEL_PRESERVE_P before inserting ENDBR. 2019-02-15 H.J. Lu <hongjiu...@intel.com> Hongtao Liu <hongtao....@intel.com> gcc/ PR target/89355 * config/i386/i386.c (rest_of_insert_endbranch): LABEL_PRESERVE_P to see if the address of NOTE_INSN_DELETED_LABEL is taken. (ix86_init_large_pic_reg): Don't set LABEL_PRESERVE_P. gcc/testsuite/ PR target/89355 * gcc.target/i386/cet-label-3.c: New test. * gcc.target/i386/cet-label-4.c: Likewise. * gcc.target/i386/cet-label-5.c: Likewise. --- gcc/config/i386/i386.c | 9 ++++---- gcc/testsuite/gcc.target/i386/cet-label-3.c | 23 +++++++++++++++++++++ gcc/testsuite/gcc.target/i386/cet-label-4.c | 12 +++++++++++ gcc/testsuite/gcc.target/i386/cet-label-5.c | 13 ++++++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/cet-label-3.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-label-4.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-label-5.c diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 609273e4fc4..acdc789b834 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2734,10 +2734,10 @@ rest_of_insert_endbranch (void) continue; } - if ((LABEL_P (insn) && LABEL_PRESERVE_P (insn)) - || (NOTE_P (insn) - && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)) - /* TODO. Check /s bit also. */ + if ((LABEL_P (insn) + || (NOTE_P (insn) + && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)) + && LABEL_PRESERVE_P (insn)) { cet_eb = gen_nop_endbr (); emit_insn_after (cet_eb, insn); @@ -6997,7 +6997,6 @@ ix86_init_large_pic_reg (unsigned int tmp_regno) gcc_assert (Pmode == DImode); label = gen_label_rtx (); emit_label (label); - LABEL_PRESERVE_P (label) = 1; tmp_reg = gen_rtx_REG (Pmode, tmp_regno); gcc_assert (REGNO (pic_offset_table_rtx) != tmp_regno); emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx, diff --git a/gcc/testsuite/gcc.target/i386/cet-label-3.c b/gcc/testsuite/gcc.target/i386/cet-label-3.c new file mode 100644 index 00000000000..9f427a866f3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-label-3.c @@ -0,0 +1,23 @@ +/* PR target/89355 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcf-protection" } */ +/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */ +int +test (int* val) +{ + int status = 99; + + if (!val) + { + status = 22; + goto end; + } + + extern int x; + *val = x; + + status = 0; +end: + return status; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-label-4.c b/gcc/testsuite/gcc.target/i386/cet-label-4.c new file mode 100644 index 00000000000..d743d2bf202 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-label-4.c @@ -0,0 +1,12 @@ +/* PR target/89355 */ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-options "-O2 -fcf-protection -fPIC -mcmodel=large" } */ +/* { dg-final { scan-assembler-times "endbr64" 1 } } */ + +extern int val; + +int +test (void) +{ + return val; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-label-5.c b/gcc/testsuite/gcc.target/i386/cet-label-5.c new file mode 100644 index 00000000000..4d5ca816598 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-label-5.c @@ -0,0 +1,13 @@ +/* PR target/89355 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcf-protection -Wno-return-local-addr" } */ +/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */ + +void * +func (void) +{ + return &&bar; +bar: + return 0; +} -- 2.20.1