> -----Original Message-----
> From: Jakub Jelinek [mailto:ja...@redhat.com]
> Sent: Wednesday, January 31, 2018 9:57 PM
> To: Uros Bizjak <ubiz...@gmail.com>; Kirill Yukhin
> <kirill.yuk...@gmail.com>
> Cc: gcc-patches@gcc.gnu.org; Tsimbalist, Igor V
> <igor.v.tsimbal...@intel.com>
> Subject: [PATCH] Fix ICE with CET and -g (PR target/84146)
> 
> Hi!
> 
> We ICE on the following test because rest_of_insert_endbranch
> separates a setjmp call from the following
> NOTE_INSN_CALL_ARG_LOCATION
> that must always immediately follow the call.
> No other note or debug insn (which aren't around after var-tracking anyway)
> needs to follow the call, so the loop it was doing is unnecessary, on the
> other side, we are already at a late state where bb boundaries are fuzzy and
> we are going to throw away the cfg before doing final.
> 
> So, all we need is just check if the call is followed by this note and
> if yes, emit the endbr after it.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Just in case, ok from CET viewpoint.

Thanks,
Igor

> 2018-01-31  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR target/84146
>       * config/i386/i386.c (rest_of_insert_endbranch): Only skip
>       NOTE_INSN_CALL_ARG_LOCATION after a call, not anything else,
>       and skip it regardless of bb boundaries.  Use CALL_P macro,
>       don't test INSN_P (insn) together with CALL_P or JUMP_P check
>       unnecessarily, formatting fix.
> 
>       * gcc.target/i386/pr84146.c: New test.
> 
> --- gcc/config/i386/i386.c.jj 2018-01-31 09:26:18.341505667 +0100
> +++ gcc/config/i386/i386.c    2018-01-31 14:13:33.815243832 +0100
> @@ -2609,31 +2609,27 @@ rest_of_insert_endbranch (void)
>        for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
>          insn = NEXT_INSN (insn))
>       {
> -       if (INSN_P (insn) && GET_CODE (insn) == CALL_INSN)
> +       if (CALL_P (insn))
>           {
>             if (find_reg_note (insn, REG_SETJMP, NULL) == NULL)
>               continue;
>             /* Generate ENDBRANCH after CALL, which can return more
> than
>                twice, setjmp-like functions.  */
> 
> -           /* Skip notes and debug insns that must be next to the
> -              call insn.  ??? This might skip a lot more than
> -              that...  ??? Skipping barriers and emitting code
> -              after them surely looks like a mistake; we probably
> -              won't ever hit it, for we'll hit BB_END first.  */
> +           /* Skip notes that must immediately follow the call insn.  */
>             rtx_insn *next_insn = insn;
> -           while ((next_insn != BB_END (bb))
> -                   && (DEBUG_INSN_P (NEXT_INSN (next_insn))
> -                       || NOTE_P (NEXT_INSN (next_insn))
> -                       || BARRIER_P (NEXT_INSN (next_insn))))
> -             next_insn = NEXT_INSN (next_insn);
> +           if (NEXT_INSN (insn)
> +               && NOTE_P (NEXT_INSN (insn))
> +               && (NOTE_KIND (NEXT_INSN (insn))
> +                   == NOTE_INSN_CALL_ARG_LOCATION))
> +             next_insn = NEXT_INSN (insn);
> 
>             cet_eb = gen_nop_endbr ();
>             emit_insn_after_setloc (cet_eb, next_insn, INSN_LOCATION
> (insn));
>             continue;
>           }
> 
> -       if (INSN_P (insn) && JUMP_P (insn) && flag_cet_switch)
> +       if (JUMP_P (insn) && flag_cet_switch)
>           {
>             rtx target = JUMP_LABEL (insn);
>             if (target == NULL_RTX || ANY_RETURN_P (target))
> @@ -2668,7 +2664,7 @@ rest_of_insert_endbranch (void)
>         if ((LABEL_P (insn) && LABEL_PRESERVE_P (insn))
>             || (NOTE_P (insn)
>                 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
> -/* TODO.  Check /s bit also.  */
> +         /* TODO.  Check /s bit also.  */
>           {
>             cet_eb = gen_nop_endbr ();
>             emit_insn_after (cet_eb, insn);
> --- gcc/testsuite/gcc.target/i386/pr84146.c.jj        2018-01-31
> 16:32:28.099929916 +0100
> +++ gcc/testsuite/gcc.target/i386/pr84146.c   2018-01-31
> 14:04:17.796122397 +0100
> @@ -0,0 +1,14 @@
> +/* PR target/84146 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -g -mcet -fcf-protection=full" } */
> +
> +int __setjmp (void **);
> +void *buf[64];
> +
> +void
> +foo (void)
> +{
> +  __setjmp (buf);
> +  for (;;)
> +    ;
> +}
> 
>       Jakub

Reply via email to