From patchwork Tue Sep 12 15:25:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 138265 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9ecd:0:b0:3f2:4152:657d with SMTP id t13csp491797vqx; Tue, 12 Sep 2023 08:35:21 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHq2LG1LMte6dW40Y2a7Z7zS30HamOlbyOxxBSqUMcSXEUqlcFT62xAYDbLZYrBY85WsQjL X-Received: by 2002:a2e:3807:0:b0:2bd:ddf:8aa9 with SMTP id f7-20020a2e3807000000b002bd0ddf8aa9mr102855lja.24.1694532921668; Tue, 12 Sep 2023 08:35:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694532921; cv=none; d=google.com; s=arc-20160816; b=WEmfQgz/7p4qCEafhnWLA+NqmscM3xk7K3gwZNNplp7G0Cw6Kgaw9q3o2X+0+ZORfm iRXf2ikkElpQQhm0FAgCN346pMmX2VSx2D+CEEYaF6VXgr9D9gcptJdPtqhKE55PDxWv teUy1owBpEaHEib4dyXAZzQWaTdx+hDS+vlkM3R4BUaPcizDQAS0MBI6U0nBZ7cWG/wf r/rn7vcW/ceLaETjNnpwPMGzckjk7qnXcVyVcgscYLhcPjRuQMMikAho0Hy73gVxwq0S 6u9ZMyvs4/XWk6mQW0bfDtcgR8M5HB7K6vvBNmS5WkRtAq5SVjlyteKzpFV6Uo4cAzOJ aEvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=BBuKunucbkTvAS+9zJbfUeKHZmdEstmK9X7iaOoP3yY=; fh=C4nEn4uRKApr1WsFtLyJD8L5BeRuRc+JFyqoopFjd9M=; b=u3/skHMqc1H7rHnZyACIfjwZPbVuYwZn0deM1UoVM4307x/ojBVEbkWxsYkIrjwQjm sB2ZJPn/jBDMnRJ6ivrIOBmPiYwmfPknAiVPkme/nO4K3cl6l/R6h2fpgzhEJ/jPvjDn Tpg8SFIlEZoEZnPVJ7zXBzYWJkh6Ctm0+EI8OzFaA+2ETOuDG16vthub3OWxTiI0yl6F wb18rUJPCrfedDKnPGdxMJTF4s+uGy3H98sSU+1WNyAH+BXRylibDLbzr24HAXUe/CRc udQnbMrx6O0i3wHIlXCiG1tGCy+07z6/lEID8UOJIogDuW+789CNyyivdpcqfHcT8J40 NMBg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=iYT26zDp; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id j25-20020a170906255900b009a1ac68daa3si8899903ejb.160.2023.09.12.08.35.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 08:35:21 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=iYT26zDp; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2E35E385558F for ; Tue, 12 Sep 2023 15:29:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2E35E385558F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1694532557; bh=BBuKunucbkTvAS+9zJbfUeKHZmdEstmK9X7iaOoP3yY=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=iYT26zDpckg1Qaf/7sAP7cuYjWFUdmAEM5wy7llYmFl9qIeS/lSkDKt/0i/+h87Ns /eVTIskidnM0YyvOcx7lLvQM18ia+cgk5IIYbmD0njGQb8rCIfPyTBi6WnmYBm9dsj RSOS4P670pcj8Xw0qoNz7IOd5k9Fc2LisZIM4www= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id E575B385E83C for ; Tue, 12 Sep 2023 15:25:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E575B385E83C Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EB5E4D75; Tue, 12 Sep 2023 08:26:25 -0700 (PDT) Received: from e121540-lin.manchester.arm.com (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2F1033F738; Tue, 12 Sep 2023 08:25:48 -0700 (PDT) To: gcc-patches@gcc.gnu.org Cc: Richard Sandiford Subject: [PATCH 15/19] aarch64: Put LR save probe in first 16 bytes Date: Tue, 12 Sep 2023 16:25:25 +0100 Message-Id: <20230912152529.3322336-16-richard.sandiford@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230912152529.3322336-1-richard.sandiford@arm.com> References: <20230912152529.3322336-1-richard.sandiford@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-23.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, SCC_10_SHORT_WORD_LINES, SCC_20_SHORT_WORD_LINES, SCC_35_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Sandiford via Gcc-patches From: Richard Sandiford Reply-To: Richard Sandiford Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776846552906597963 X-GMAIL-MSGID: 1776846552906597963 -fstack-clash-protection uses the save of LR as a probe for the next allocation. The next allocation could be: * another part of the static frame, e.g. when allocating SVE save slots or outgoing arguments * an alloca in the same function * an allocation made by a callee function However, when -fomit-frame-pointer is used, the LR save slot is placed above the other GPR save slots. It could therefore be up to 80 bytes above the base of the GPR save area (which is also the hard fp address). aarch64_allocate_and_probe_stack_space took this into account when deciding how much subsequent space could be allocated without needing a probe. However, it interacted badly with: /* If doing a small final adjustment, we always probe at offset 0. This is done to avoid issues when LR is not at position 0 or when the final adjustment is smaller than the probing offset. */ else if (final_adjustment_p && rounded_size == 0) residual_probe_offset = 0; which forces any allocation that is smaller than the guard page size to be probed at offset 0 rather than the usual offset 1024. It was therefore possible to construct cases in which we had: * a probe using LR at SP + 80 bytes (or some other value >= 16) * an allocation of the guard page size - 16 bytes * a probe at SP + 0 which allocates guard page size + 64 consecutive unprobed bytes. This patch requires the LR probe to be in the first 16 bytes of the save area when stack clash protection is active. Doing it unconditionally would cause code-quality regressions. Putting LR before other registers prevents push/pop allocation when shadow call stacks are enabled, since LR is restored separately from the other callee-saved registers. The new comment doesn't say that the probe register is required to be LR, since a later patch removes that restriction. gcc/ * config/aarch64/aarch64.cc (aarch64_layout_frame): Ensure that the LR save slot is in the first 16 bytes of the register save area. Only form STP/LDP push/pop candidates if both registers are valid. (aarch64_allocate_and_probe_stack_space): Remove workaround for when LR was not in the first 16 bytes. gcc/testsuite/ * gcc.target/aarch64/stack-check-prologue-18.c: New test. * gcc.target/aarch64/stack-check-prologue-19.c: Likewise. * gcc.target/aarch64/stack-check-prologue-20.c: Likewise. --- gcc/config/aarch64/aarch64.cc | 72 ++++++------- .../aarch64/stack-check-prologue-18.c | 100 ++++++++++++++++++ .../aarch64/stack-check-prologue-19.c | 100 ++++++++++++++++++ .../aarch64/stack-check-prologue-20.c | 3 + 4 files changed, 233 insertions(+), 42 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index b942bf3de4a..383b32f2078 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -8573,26 +8573,34 @@ aarch64_layout_frame (void) bool saves_below_hard_fp_p = maybe_ne (frame.below_hard_fp_saved_regs_size, 0); frame.bytes_below_hard_fp = offset; + + auto allocate_gpr_slot = [&](unsigned int regno) + { + frame.reg_offset[regno] = offset; + if (frame.wb_push_candidate1 == INVALID_REGNUM) + frame.wb_push_candidate1 = regno; + else if (frame.wb_push_candidate2 == INVALID_REGNUM) + frame.wb_push_candidate2 = regno; + offset += UNITS_PER_WORD; + }; + if (frame.emit_frame_chain) { /* FP and LR are placed in the linkage record. */ - frame.reg_offset[R29_REGNUM] = offset; - frame.wb_push_candidate1 = R29_REGNUM; - frame.reg_offset[R30_REGNUM] = offset + UNITS_PER_WORD; - frame.wb_push_candidate2 = R30_REGNUM; - offset += 2 * UNITS_PER_WORD; + allocate_gpr_slot (R29_REGNUM); + allocate_gpr_slot (R30_REGNUM); } + else if (flag_stack_clash_protection + && known_eq (frame.reg_offset[R30_REGNUM], SLOT_REQUIRED)) + /* Put the LR save slot first, since it makes a good choice of probe + for stack clash purposes. The idea is that the link register usually + has to be saved before a call anyway, and so we lose little by + stopping it from being individually shrink-wrapped. */ + allocate_gpr_slot (R30_REGNUM); for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++) if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) - { - frame.reg_offset[regno] = offset; - if (frame.wb_push_candidate1 == INVALID_REGNUM) - frame.wb_push_candidate1 = regno; - else if (frame.wb_push_candidate2 == INVALID_REGNUM) - frame.wb_push_candidate2 = regno; - offset += UNITS_PER_WORD; - } + allocate_gpr_slot (regno); poly_int64 max_int_offset = offset; offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); @@ -8670,10 +8678,13 @@ aarch64_layout_frame (void) max_push_offset to 0, because no registers are popped at this time, so callee_adjust cannot be adjusted. */ HOST_WIDE_INT max_push_offset = 0; - if (frame.wb_pop_candidate2 != INVALID_REGNUM) - max_push_offset = 512; - else if (frame.wb_pop_candidate1 != INVALID_REGNUM) - max_push_offset = 256; + if (frame.wb_pop_candidate1 != INVALID_REGNUM) + { + if (frame.wb_pop_candidate2 != INVALID_REGNUM) + max_push_offset = 512; + else + max_push_offset = 256; + } HOST_WIDE_INT const_size, const_below_saved_regs, const_above_fp; HOST_WIDE_INT const_saved_regs_size; @@ -9703,29 +9714,6 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, = (final_adjustment_p ? guard_used_by_caller + byte_sp_alignment : guard_size - guard_used_by_caller); - /* When doing the final adjustment for the outgoing arguments, take into - account any unprobed space there is above the current SP. There are - two cases: - - - When saving SVE registers below the hard frame pointer, we force - the lowest save to take place in the prologue before doing the final - adjustment (i.e. we don't allow the save to be shrink-wrapped). - This acts as a probe at SP, so there is no unprobed space. - - - When there are no SVE register saves, we use the store of the link - register as a probe. We can't assume that LR was saved at position 0 - though, so treat any space below it as unprobed. */ - if (final_adjustment_p - && known_eq (frame.below_hard_fp_saved_regs_size, 0)) - { - poly_int64 lr_offset = (frame.reg_offset[LR_REGNUM] - - frame.bytes_below_saved_regs); - if (known_ge (lr_offset, 0)) - min_probe_threshold -= lr_offset.to_constant (); - else - gcc_assert (!flag_stack_clash_protection || known_eq (poly_size, 0)); - } - poly_int64 frame_size = frame.frame_size; /* We should always have a positive probe threshold. */ @@ -9905,8 +9893,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, if (final_adjustment_p && rounded_size != 0) min_probe_threshold = 0; /* If doing a small final adjustment, we always probe at offset 0. - This is done to avoid issues when LR is not at position 0 or when - the final adjustment is smaller than the probing offset. */ + This is done to avoid issues when the final adjustment is smaller + than the probing offset. */ else if (final_adjustment_p && rounded_size == 0) residual_probe_offset = 0; diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c new file mode 100644 index 00000000000..82447d20fff --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c @@ -0,0 +1,100 @@ +/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +void f(int, ...); +void g(); + +/* +** test1: +** ... +** str x30, \[sp\] +** sub sp, sp, #4064 +** str xzr, \[sp\] +** cbnz w0, .* +** bl g +** ... +** str x26, \[sp, #?4128\] +** ... +*/ +int test1(int z) { + __uint128_t x = 0; + int y[0x400]; + if (z) + { + asm volatile ("" ::: + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); + f(0, 0, 0, 0, 0, 0, 0, &y, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x); + } + g(); + return 1; +} + +/* +** test2: +** ... +** str x30, \[sp\] +** sub sp, sp, #1040 +** str xzr, \[sp\] +** cbnz w0, .* +** bl g +** ... +*/ +int test2(int z) { + __uint128_t x = 0; + int y[0x400]; + if (z) + { + asm volatile ("" ::: + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); + f(0, 0, 0, 0, 0, 0, 0, &y, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x); + } + g(); + return 1; +} + +/* +** test3: +** ... +** str x30, \[sp\] +** sub sp, sp, #1024 +** cbnz w0, .* +** bl g +** ... +*/ +int test3(int z) { + __uint128_t x = 0; + int y[0x400]; + if (z) + { + asm volatile ("" ::: + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); + f(0, 0, 0, 0, 0, 0, 0, &y, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); + } + g(); + return 1; +} diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c new file mode 100644 index 00000000000..73ac3e4e4eb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c @@ -0,0 +1,100 @@ +/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12 -fsanitize=shadow-call-stack -ffixed-x18" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +void f(int, ...); +void g(); + +/* +** test1: +** ... +** str x30, \[sp\] +** sub sp, sp, #4064 +** str xzr, \[sp\] +** cbnz w0, .* +** bl g +** ... +** str x26, \[sp, #?4128\] +** ... +*/ +int test1(int z) { + __uint128_t x = 0; + int y[0x400]; + if (z) + { + asm volatile ("" ::: + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); + f(0, 0, 0, 0, 0, 0, 0, &y, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x); + } + g(); + return 1; +} + +/* +** test2: +** ... +** str x30, \[sp\] +** sub sp, sp, #1040 +** str xzr, \[sp\] +** cbnz w0, .* +** bl g +** ... +*/ +int test2(int z) { + __uint128_t x = 0; + int y[0x400]; + if (z) + { + asm volatile ("" ::: + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); + f(0, 0, 0, 0, 0, 0, 0, &y, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x); + } + g(); + return 1; +} + +/* +** test3: +** ... +** str x30, \[sp\] +** sub sp, sp, #1024 +** cbnz w0, .* +** bl g +** ... +*/ +int test3(int z) { + __uint128_t x = 0; + int y[0x400]; + if (z) + { + asm volatile ("" ::: + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); + f(0, 0, 0, 0, 0, 0, 0, &y, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); + } + g(); + return 1; +} diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c new file mode 100644 index 00000000000..690aae8dfd5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c @@ -0,0 +1,3 @@ +/* { dg-options "-O2 -fstack-protector-all -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12 -fsanitize=shadow-call-stack -ffixed-x18" } */ + +#include "stack-check-prologue-19.c"