From: Alex Coplan Date: Wed, 21 Apr 2021 13:42:04 +0000 (+0100) Subject: aarch64: Avoid duplicating bti j insns for jump tables [PR99988] X-Git-Tag: upstream/12.2.0~8663 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fe11882ae34c49f6214f93867783ed1332f35f0f;p=platform%2Fupstream%2Fgcc.git aarch64: Avoid duplicating bti j insns for jump tables [PR99988] This patch fixes PR99988 which shows us generating large (> 250) sequences of back-to-back bti j instructions. The fix is simply to avoid inserting bti j instructions at the target of a jump table if we've already inserted one for a given label. gcc/ChangeLog: PR target/99988 * config/aarch64/aarch64-bti-insert.c (aarch64_bti_j_insn_p): New. (rest_of_insert_bti): Avoid inserting duplicate bti j insns for jump table targets. gcc/testsuite/ChangeLog: PR target/99988 * gcc.target/aarch64/pr99988.c: New test. --- diff --git a/gcc/config/aarch64/aarch64-bti-insert.c b/gcc/config/aarch64/aarch64-bti-insert.c index 9366497..5d6bc16 100644 --- a/gcc/config/aarch64/aarch64-bti-insert.c +++ b/gcc/config/aarch64/aarch64-bti-insert.c @@ -120,6 +120,17 @@ aarch64_pac_insn_p (rtx x) return false; } +/* Check if INSN is a BTI J insn. */ +static bool +aarch64_bti_j_insn_p (rtx_insn *insn) +{ + if (!insn || !INSN_P (insn)) + return false; + + rtx pat = PATTERN (insn); + return GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_BTI_J; +} + /* Insert the BTI instruction. */ /* This is implemented as a late RTL pass that runs before branch shortening and does the following. */ @@ -165,6 +176,10 @@ rest_of_insert_bti (void) for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j) { label = as_a (XEXP (RTVEC_ELT (vec, j), 0)); + rtx_insn *next = next_nonnote_nondebug_insn (label); + if (aarch64_bti_j_insn_p (next)) + continue; + 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 0000000..2d87f41 --- /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(); + } +}