Looks good in general, but like you say, it's GCC 12 material.

Alex Coplan <alex.cop...@arm.com> writes:
> diff --git a/gcc/config/aarch64/aarch64-bti-insert.c 
> b/gcc/config/aarch64/aarch64-bti-insert.c
> index 936649769c7..943fa3c1097 100644
> --- a/gcc/config/aarch64/aarch64-bti-insert.c
> +++ b/gcc/config/aarch64/aarch64-bti-insert.c
> @@ -120,6 +120,13 @@ aarch64_pac_insn_p (rtx x)
>    return false;
>  }
>  
> +static bool
> +aarch64_bti_j_insn_p (rtx_insn *insn)
> +{
> +  rtx pat = PATTERN (insn);
> +  return GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_BTI_J;
> +}
> +

Nit, but even a simple function like this should have a comment. :-)

>  /* Insert the BTI instruction.  */
>  /* This is implemented as a late RTL pass that runs before branch
>     shortening and does the following.  */
> @@ -165,6 +172,9 @@ rest_of_insert_bti (void)
>                 for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
>                   {
>                     label = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, j), 0));
> +                   if (aarch64_bti_j_insn_p (next_nonnote_insn (label)))
> +                     continue;
> +

This should be next_nonnote_nondebug_insn (quite the mouthful),
otherwise debug instructions could affect the choice.

The thing returned by next_nonnote_nondebug_insn isn't in general
guaranteed to be an insn (unlike next_real_nondebug_insn).  It might
also be null in very odd cases.  I think we should therefore check
for null and INSN_P before checking PATTERN.

Thanks,
Richard

>                     bti_insn = gen_bti_j ();
>                     emit_insn_after (bti_insn, label);
>                   }
> diff --git a/gcc/testsuite/gcc.target/aarch64/pr99988.c 
> b/gcc/testsuite/gcc.target/aarch64/pr99988.c
> new file mode 100644
> index 00000000000..2d87f41a717
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/pr99988.c
> @@ -0,0 +1,66 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mbranch-protection=standard" } */
> +/* { dg-final { scan-assembler-times {bti j} 13 } } */
> +int a;
> +int c();
> +int d();
> +int e();
> +int f();
> +int g();
> +void h() {
> +  switch (a) {
> +  case 0:
> +  case 56:
> +  case 57:
> +    break;
> +  case 58:
> +  case 59:
> +  case 61:
> +  case 62:
> +    c();
> +  case 64:
> +  case 63:
> +    d();
> +  case 66:
> +  case 65:
> +    d();
> +  case 68:
> +  case 67:
> +    d();
> +  case 69:
> +  case 70:
> +    d();
> +  case 71:
> +  case 72:
> +  case 88:
> +  case 87:
> +    d();
> +  case 90:
> +  case 89:
> +    d();
> +  case 92:
> +  case 1:
> +    d();
> +  case 93:
> +  case 73:
> +  case 4:
> +    e();
> +  case 76:
> +  case 5:
> +    f();
> +  case 7:
> +  case 8:
> +  case 84:
> +  case 85:
> +    break;
> +  case 6:
> +  case 299:
> +  case 9:
> +  case 80:
> +  case 2:
> +  case 3:
> +    e();
> +  default:
> +    g();
> +  }
> +}

Reply via email to