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(); > + } > +}