From patchwork Wed Jul 24 18:00:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raphael Moreira Zinsly X-Patchwork-Id: 1964453 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ventanamicro.com header.i=@ventanamicro.com header.a=rsa-sha256 header.s=google header.b=G70CADjt; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WThdl6GSlz1yXx for ; Thu, 25 Jul 2024 04:00:59 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1EE1E3860776 for ; Wed, 24 Jul 2024 18:00:58 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id 006EE3858D29 for ; Wed, 24 Jul 2024 18:00:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 006EE3858D29 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=ventanamicro.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 006EE3858D29 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844029; cv=none; b=hQLKWCPOVoPgMp6xeTPDSL7cK7CEGDCzdTSJGhcfjuhBao2ozNhhkLeSxtycj80szUkhM1EDKPvR2kPaU1wLVWSpwyKeAApGTgqPd7GfVylwKEqMwStiYYyDUhneNnT450+/typo7f3+kxBrsGRpcYaDuC7Olfllr6OlEaELx7Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844029; c=relaxed/simple; bh=TgDaA3gP1DCSdixn2ueo/mM98GddEUCuG6l/UTxy77g=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=ESBvU2422Sv2Vy+eI5LUrSBD3tMOzPjKu0K5cqAwHFSHppyLPdbVo2x433mG3Pd/XTdxAjGC2hE5N4uYf2fvbj7it/HH5NKG1eCgDQDacJs8c6TASUdpKfxLHbbJu2J9lmusmUKU7PFv5b7e5cBfFgNe0vF5ZNdNczp8pZkOgY4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1fdd6d81812so417445ad.1 for ; Wed, 24 Jul 2024 11:00:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1721844025; x=1722448825; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sCg0+5P9Lzc8nc6Q/oyZEdJYkZtG+5SJfdcdtqsC+3w=; b=G70CADjt7c1C90i+xfiKtKz5W99R2kVG+dhC6/B+vYvkFaWC5WycJrX4D4hv4oeKUx 2Kcom4aaAPgtC2OOYjh9HFXCQR0v/fEGDKcsgS6mKlmD2qtovZItQYlih6B/mCzkKcU+ hy6ABXlPIPRtiqCGKVlpHUde9XuLcgzXqAThLYQ9Jcjnypp+k0DFuYtwWJw3MBMTplsI Q9qUpm8cISQAbOUKTiG4jafETeM7fvuNyXRJiTTjDQByLX600ms72dRw1n5EqqQ5LVJ9 hp77ydubUkgKK+oBkM64QhTsdD972x3i5eK3gX5cLJRov24x6lpoBAMn4acdfueOATbJ doXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721844025; x=1722448825; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sCg0+5P9Lzc8nc6Q/oyZEdJYkZtG+5SJfdcdtqsC+3w=; b=bxBzn+YXpuEibx8gGF+7C1MtzpThkWjyiruTNIU7n2hIkmGL30v6ddGWHoxE6evsCo CfIcB9zXJ4WkzwdY8SucyW6VdtYlH1A5v+k+Cg64tMyNIzgtubSniaE7s9LNTvEF8qFF ucBztMxGTJb9XK1U7d66dvGqDm92Vf2+gv7XcJwkeulcCz+Y2VTaxQV+ryoy4UReCpNV p9qNAIfNKqIEVGuPMvoyfK77xNknq80DgoBIKdP1KfzmGwwaOnn3MwDexu514ZSqI6Hv 18IMJjCm8zz57tyz3CRqj6dIhkMFd9ViopRsdYWy2pHyesDovvYeOBS59AF9Jp4tXp1g iWGQ== X-Gm-Message-State: AOJu0Ywxq5gtD97zaJDg+aqIEZHx5qBjkRxmEK2UTvTAaOafGsZNd9l7 VhQbfB0ESz1Meskf3qSi8OGwofhxg+XMvK41YMmiYN0AFEFn8l9pQcTLUu4BYgqTAfEgguUxGN8 T X-Google-Smtp-Source: AGHT+IGToDVQ1VAFi9k8JNkdeJkL1jBGaaYT0C2UetU4B2RNV/VkQW9wPnQnto+5qjPsnHhlMEmZpA== X-Received: by 2002:a17:903:228a:b0:1fd:927e:7d23 with SMTP id d9443c01a7336-1fed3aea8b0mr3492855ad.42.1721844025238; Wed, 24 Jul 2024 11:00:25 -0700 (PDT) Received: from marvin.dc1.ventanamicro.com ([189.4.72.88]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fd6f4713f8sm97261705ad.268.2024.07.24.11.00.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Jul 2024 11:00:24 -0700 (PDT) From: Raphael Moreira Zinsly To: gcc-patches@gcc.gnu.org Cc: jlaw@ventanamicro.com, Raphael Moreira Zinsly Subject: [PATCH 1/5] RISC-V: Small stack tie changes Date: Wed, 24 Jul 2024 15:00:09 -0300 Message-ID: X-Mailer: git-send-email 2.42.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK 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: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Enable the register used by riscv_emit_stack_tie () to be passed as an argument so we can tie the stack with other registers besides hard_frame_pointer_rtx. Also don't allow operand 1 of stack_tie to be optimized to sp in preparation for the stack clash protection support. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_emit_stack_tie): Pass the register to be tied to the stack pointer as argument. * config/riscv/riscv.md (stack_tie): Don't match equal operands. --- gcc/config/riscv/riscv.cc | 18 +++++++++--------- gcc/config/riscv/riscv.md | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 19b9b2daa95..f85d018c514 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7891,12 +7891,12 @@ riscv_adjust_multi_push_cfi_prologue (int saved_size) } static void -riscv_emit_stack_tie (void) +riscv_emit_stack_tie (rtx reg) { if (Pmode == SImode) - emit_insn (gen_stack_tiesi (stack_pointer_rtx, hard_frame_pointer_rtx)); + emit_insn (gen_stack_tiesi (stack_pointer_rtx, reg)); else - emit_insn (gen_stack_tiedi (stack_pointer_rtx, hard_frame_pointer_rtx)); + emit_insn (gen_stack_tiedi (stack_pointer_rtx, reg)); } /*zcmp multi push and pop code_for_push_pop function ptr array */ @@ -8077,7 +8077,7 @@ riscv_expand_prologue (void) GEN_INT ((frame->hard_frame_pointer_offset - remaining_size).to_constant ())); RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); } /* Save the V registers. */ @@ -8108,7 +8108,7 @@ riscv_expand_prologue (void) allocation is ordered WRT fp setup and subsequent writes into the frame. */ if (frame_pointer_needed) - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); return; } @@ -8147,7 +8147,7 @@ riscv_expand_prologue (void) allocation is ordered WRT fp setup and subsequent writes into the frame. */ if (frame_pointer_needed) - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); } } @@ -8282,7 +8282,7 @@ riscv_expand_epilogue (int style) if (cfun->calls_alloca) { /* Emit a barrier to prevent loads from a deallocated stack. */ - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); need_barrier_p = false; poly_int64 adjust_offset = -frame->hard_frame_pointer_offset; @@ -8376,7 +8376,7 @@ riscv_expand_epilogue (int style) if (known_gt (step1, 0)) { /* Emit a barrier to prevent loads from a deallocated stack. */ - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); need_barrier_p = false; /* Restore the scalable frame which is assigned in prologue. */ @@ -8476,7 +8476,7 @@ riscv_expand_epilogue (int style) frame->mask = mask; /* Undo the above fib. */ if (need_barrier_p) - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); /* Deallocate the final bit of the frame. */ if (step2.to_constant () > 0) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 46c46039c33..5780c5abacf 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3969,7 +3969,7 @@ (unspec:BLK [(match_operand:X 0 "register_operand" "r") (match_operand:X 1 "register_operand" "r")] UNSPEC_TIE))] - "" + "!rtx_equal_p (operands[0], operands[1])" "" [(set_attr "type" "ghost") (set_attr "length" "0")] From patchwork Wed Jul 24 18:00:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raphael Moreira Zinsly X-Patchwork-Id: 1964454 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ventanamicro.com header.i=@ventanamicro.com header.a=rsa-sha256 header.s=google header.b=CngFSPft; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WThdn3K5wz1yXx for ; Thu, 25 Jul 2024 04:01:01 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A79F3385DDD7 for ; Wed, 24 Jul 2024 18:00:59 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by sourceware.org (Postfix) with ESMTPS id B7CEF3858C66 for ; Wed, 24 Jul 2024 18:00:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B7CEF3858C66 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=ventanamicro.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B7CEF3858C66 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::630 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844031; cv=none; b=TuOE4DZVKGylaDOxtUG5pUl/hTmEz0TduilJ2pdtrgMq/U5Sajpe1PjoWlzug1ybEqoVA/6/4exnbAFFRGnlAddzig4b+TzZ3AE4wkNKQDI+pXlNLgi1NRbxoeOf6tTHA+H3lBcGXV2ir3yqyBnfAmHWwlUks7KNGl8Fr63Gs8A= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844031; c=relaxed/simple; bh=DJWRs8WDc0gRf16l70ndBVTnlV/YZVUGYjV3tj7ZdeY=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=RbHhRdC3+Y75CC5M6roGRAlfDhcf7Gpw7pj+Svp6wDc8k2FUKpM/kl/7i0U2DIH9G3tyK3vQ4D6AUcHyRWhbSdGYs/6qF7kTK34hbAFd4etajATdG/arV4gWdp/2Qr8AW4XUc6A5z1kQetPe0pGtPFvcRMSU8sciRUC9pB31s0k= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-1fda7fa60a9so407175ad.3 for ; Wed, 24 Jul 2024 11:00:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1721844027; x=1722448827; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BJUMxLRBjPM4ggFIOmxgw7uwXrk5amAVvKJSmoDP/+E=; b=CngFSPftuxt04eSGvo4I0ML5diW6KvgtcVImnhPMdKIoBpEGocZSz3TFJBQvohMnpd 3GCpyUX6kZO0bXTpuIGnAIDobS97la9l7KBya5GTsOBA1t1kZcoUDg9SPexHiCW96bfZ iFbyOtUT0VVCRrmfah/slKkg6+qBtDIaNaX+E40CGsMs75xpSS6ZC6GG0FnhDfmUyQtf WCBeJqACc4Rt2THNXvDNn8V0W2pC1k3HGDhTvXDgUepdATVyEcGdOqNERuS6AH5WkPcI XABWnFW2dg4iKmP0Sy6g2HNw9g0Ji7wMLqVEi84vubigtHwJoAHEMVeMnCZF9JeiQ/d5 s7Ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721844027; x=1722448827; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BJUMxLRBjPM4ggFIOmxgw7uwXrk5amAVvKJSmoDP/+E=; b=bDm5xal7gsFVN7NZahuJtaCYFPv0v1zzV+sbDr8pw9BKZOHpkLXiQMXLy1HQqXADXK b8/bykEGfWPdwRg8NU+CiO0F1JG0b/AzSEzor1EJLR2y5INpMrVLOgEHWBCyk1eot8wy xQBzA3kbnhX4B/fRPL/qZzBb3XungFgkKL6hCc8IPZVebSeedWQ/PexhKXThpJvwZX5y I8tJ2s/WX+hZAakeMf4FruejxuZ3/S6yh1PS7/cLGdT8Y5jVq3tzgUskwFyi0qvr5B61 ynUKIDQiXg5Pt3YPWIqz/ugEW8eEqDn3qyUGtC7JEA1FPqSxT2d2fImZVrFYIhGm//BR 8eDA== X-Gm-Message-State: AOJu0YwjuVsumz8UP4toLkQ0NbSTsTjAD087k82/kJF0IH+jivFE8sd9 ubQi4xPSgd3YTEPbO0J+jx9Dx8VeLJHe5ddd9FsTK6nWjU+AAn72PtSrs1SLJv7RPXpWcPBnkLF D X-Google-Smtp-Source: AGHT+IFjwmUgLUTmQIxpAb/wsc1SUYwUHbxjqaRJjIpz0J6rwnnj6uFB5k1UL9QwQPAtajEL2B+uUA== X-Received: by 2002:a17:902:ec8d:b0:1fd:abd4:ed5b with SMTP id d9443c01a7336-1fed38c38b7mr3149055ad.39.1721844027275; Wed, 24 Jul 2024 11:00:27 -0700 (PDT) Received: from marvin.dc1.ventanamicro.com ([189.4.72.88]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fd6f4713f8sm97261705ad.268.2024.07.24.11.00.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Jul 2024 11:00:26 -0700 (PDT) From: Raphael Moreira Zinsly To: gcc-patches@gcc.gnu.org Cc: jlaw@ventanamicro.com, Raphael Moreira Zinsly Subject: [PATCH 2/5] RISC-V: Move riscv_v_adjust_scalable_frame Date: Wed, 24 Jul 2024 15:00:10 -0300 Message-ID: X-Mailer: git-send-email 2.42.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-10.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK 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: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Move riscv_v_adjust_scalable_frame () in preparation for the stack clash protection support. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_v_adjust_scalable_frame): Move closer to riscv_expand_prologue. --- gcc/config/riscv/riscv.cc | 62 +++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index f85d018c514..89fc8966654 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3122,37 +3122,6 @@ riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src) } } -/* Adjust scalable frame of vector for prologue && epilogue. */ - -static void -riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue) -{ - rtx tmp = RISCV_PROLOGUE_TEMP (Pmode); - rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode); - rtx insn, dwarf, adjust_frame_rtx; - - riscv_legitimize_poly_move (Pmode, adjust_size, tmp, - gen_int_mode (offset, Pmode)); - - if (epilogue) - insn = gen_add3_insn (target, target, adjust_size); - else - insn = gen_sub3_insn (target, target, adjust_size); - - insn = emit_insn (insn); - - RTX_FRAME_RELATED_P (insn) = 1; - - adjust_frame_rtx - = gen_rtx_SET (target, - plus_constant (Pmode, target, epilogue ? offset : -offset)); - - dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx), - NULL_RTX); - - REG_NOTES (insn) = dwarf; -} - /* Take care below subreg const_poly_int move: 1. (set (subreg:DI (reg:TI 237) 8) @@ -7928,6 +7897,37 @@ static const code_for_push_pop_t code_for_push_pop[ZCMP_MAX_GRP_SLOTS][ZCMP_OP_N code_for_gpr_multi_popret_up_to_s11, code_for_gpr_multi_popretz_up_to_s11}}; +/* Adjust scalable frame of vector for prologue && epilogue. */ + +static void +riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue) +{ + rtx tmp = RISCV_PROLOGUE_TEMP (Pmode); + rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode); + rtx insn, dwarf, adjust_frame_rtx; + + riscv_legitimize_poly_move (Pmode, adjust_size, tmp, + gen_int_mode (offset, Pmode)); + + if (epilogue) + insn = gen_add3_insn (target, target, adjust_size); + else + insn = gen_sub3_insn (target, target, adjust_size); + + insn = emit_insn (insn); + + RTX_FRAME_RELATED_P (insn) = 1; + + adjust_frame_rtx + = gen_rtx_SET (target, + plus_constant (Pmode, target, epilogue ? offset : -offset)); + + dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx), + NULL_RTX); + + REG_NOTES (insn) = dwarf; +} + static rtx riscv_gen_multi_push_pop_insn (riscv_zcmp_op_t op, HOST_WIDE_INT adj_size, unsigned int regs_num) From patchwork Wed Jul 24 18:00:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raphael Moreira Zinsly X-Patchwork-Id: 1964457 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ventanamicro.com header.i=@ventanamicro.com header.a=rsa-sha256 header.s=google header.b=BXa6iGyv; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WThg71QwXz1yXx for ; Thu, 25 Jul 2024 04:02:11 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6D3A2386100A for ; Wed, 24 Jul 2024 18:02:09 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by sourceware.org (Postfix) with ESMTPS id E89373858283 for ; Wed, 24 Jul 2024 18:00:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E89373858283 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=ventanamicro.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E89373858283 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::636 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844038; cv=none; b=PSUJNXVL54fNCY0YZ8RvGUMrzD6wz9CEGLFm5Lxdx8Nub34D32yG+31lIWseeLcDp7c9FKzWAptHtGwOkRLP4nqikpnYoaPkfD4uI9720nkVmJjku2Dke5Wi634ods2IYSxMICXmWEyOl0pFiiVepM0IJq5N1Jrn+PufJKE/qvk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844038; c=relaxed/simple; bh=8/nrGhtgf8NbwT0aFliCyyr7ATQuM+9m7sjTFEQapDY=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=g/+LXmX5MblPp3/sA5GeYDo34iberH525HhvYv2Q3eRNxcc5hSo/ERPdP+3EbXtW0ek93+MMLiK0aDNyZmYRwezw9bxcsfTzcIRA5OYVNm6Sm4tAECcZuU2mi0kqOjvn14G1CEVzHrFAaV+RWYZTuy7zy29w8nXDo73yBIo7NN4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-1fb3b7d0d3aso224025ad.2 for ; Wed, 24 Jul 2024 11:00:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1721844030; x=1722448830; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=L5UGLe2o8A1NsPPbyEgyxerQOTzVJ4hlPK+gvwR4cQA=; b=BXa6iGyvFCDlNwanca/k+QsufmRAHMbFT056KTVu04v4ezIKII4NbPtKwf2CwyzqYt UAcmRSZZJZWGm4ZTzDt/bbE6AO11GtCrc52KEmLFCYxvOwYHxtRe6Xw7VTj+1V66nzPa j0hxkhdcJCPsgu8Rl0jQ0GM3Klo4zgDB7O1DpXtNrQfX1qYd0jbwXPNT72qQOoe/qi5J L3rtln/a1iKw16121IS1Xjz61c/iWWDkkYcmxuHEY7Dh6CQiwSKKu3I4LA4Hk7hNiCzY 0wLfHSTjUXZKAa0QMPKhbJjc6+NtGVgKz3oES5VbLjdt2fLtf3RpDXMxIYzjb6V9tvgP wkrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721844030; x=1722448830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=L5UGLe2o8A1NsPPbyEgyxerQOTzVJ4hlPK+gvwR4cQA=; b=LDpsTvtyJZBNIpeqhBSZ2oufl4pMXujpBtgf0R/w6YljYh4d9WaRkcJPXAB4o+H0UC bAslh6WPdb9JgwYbNA9SwekpZhHCEv/Fv9k/VGd6X/+uOkE/3qsXTasckFaHB03CxBnh 7JB8qr1mBv22+lsD5GNn8d2k0XMEs35QODYFZ+PwN0cwfUkPXD8Eq3UGfYgWEvgw5fk9 Dalb/3RbRWaZ7xuGF4ye8OpsprwVKjZ5LxB7Him/zqvJvBDxn8u1qhfhii0kgMX59DjQ hXc7NyTW8rkY5nzVPUcnapHbyIorAs+6u3V8Znpnaujn8gqkkA35AKWQDAtpuWMReIMy x0aw== X-Gm-Message-State: AOJu0YwxqFAagTmLSYinCdMKbo41j0nVS7E6sUX+pCDeJU4UpvWOL49E vYwdE3CEtQaA88hnwYfUt6l8R2z0LHXfanqxmP8741WhAl9Uf9MrSGaNK0XO/8qgjGW0WExXksP J X-Google-Smtp-Source: AGHT+IEMpG819XjvoCn7vAzlH8//4110kDxTRNqAksOOaVQGKv8V0L9ZU91acAElOy2GT0SXdYTdMQ== X-Received: by 2002:a17:902:e54c:b0:1fa:4187:7397 with SMTP id d9443c01a7336-1fed3bf03f0mr3541775ad.60.1721844029431; Wed, 24 Jul 2024 11:00:29 -0700 (PDT) Received: from marvin.dc1.ventanamicro.com ([189.4.72.88]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fd6f4713f8sm97261705ad.268.2024.07.24.11.00.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Jul 2024 11:00:29 -0700 (PDT) From: Raphael Moreira Zinsly To: gcc-patches@gcc.gnu.org Cc: jlaw@ventanamicro.com, Raphael Moreira Zinsly Subject: [PATCH 3/5] RISC-V: Stack-clash protection implemention Date: Wed, 24 Jul 2024 15:00:11 -0300 Message-ID: <6f8bab519688aed305898320d1735409e4c46e10.1721681845.git.rzinsly@ventanamicro.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK 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: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This implements stack-clash protection for riscv, with riscv_allocate_and_probe_stack_space being based of aarch64_allocate_and_probe_stack_space from aarch64's implementation. We enforce the probing interval and the guard size to always be equal, their default value is 4Kb which is riscv page size. We also probe up by 1024 bytes in the general case when a probe is required. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_option_override): Enforce that interval is the same size as guard size. (riscv_allocate_and_probe_stack_space): New function. (riscv_expand_prologue): Call riscv_allocate_and_probe_stack_space to the final allocation of the stack and add stack-clash dump information. * config/riscv/riscv.h: Define STACK_CLASH_CALLER_GUARD and STACK_CLASH_MAX_UNROLL_PAGES. gcc/testsuite/ChangeLog: * gcc.dg/params/blocksort-part.c: Skip riscv for stack-clash protection intervals. * gcc.dg/pr82788.c: Skip riscv. * gcc.dg/stack-check-6.c: Skip residual check for riscv. * gcc.dg/stack-check-6a.c: Skip riscv. * gcc.target/riscv/stack-check-12.c: New test. * gcc.target/riscv/stack-check-13.c: New test. * gcc.target/riscv/stack-check-cfa-1.c: New test. * gcc.target/riscv/stack-check-cfa-2.c: New test. * gcc.target/riscv/stack-check-prologue-1.c: New test. * gcc.target/riscv/stack-check-prologue-10.c: New test. * gcc.target/riscv/stack-check-prologue-11.c: New test. * gcc.target/riscv/stack-check-prologue-12.c: New test. * gcc.target/riscv/stack-check-prologue-13.c: New test. * gcc.target/riscv/stack-check-prologue-14.c: New test. * gcc.target/riscv/stack-check-prologue-15.c: New test. * gcc.target/riscv/stack-check-prologue-2.c: New test. * gcc.target/riscv/stack-check-prologue-3.c: New test. * gcc.target/riscv/stack-check-prologue-4.c: New test. * gcc.target/riscv/stack-check-prologue-5.c: New test. * gcc.target/riscv/stack-check-prologue-6.c: New test. * gcc.target/riscv/stack-check-prologue-7.c: New test. * gcc.target/riscv/stack-check-prologue-8.c: New test. * gcc.target/riscv/stack-check-prologue-9.c: New test. * gcc.target/riscv/stack-check-prologue.h: New file. * lib/target-supports.exp (check_effective_target_supports_stack_clash_protection): Add riscv. (check_effective_target_caller_implicit_probes): Likewise. --- gcc/config/riscv/riscv.cc | 244 +++++++++++++++--- gcc/config/riscv/riscv.h | 8 + gcc/testsuite/gcc.dg/params/blocksort-part.c | 2 +- gcc/testsuite/gcc.dg/pr82788.c | 2 +- gcc/testsuite/gcc.dg/stack-check-6.c | 2 +- gcc/testsuite/gcc.dg/stack-check-6a.c | 2 +- .../gcc.target/riscv/stack-check-12.c | 23 ++ .../gcc.target/riscv/stack-check-13.c | 26 ++ .../gcc.target/riscv/stack-check-cfa-1.c | 12 + .../gcc.target/riscv/stack-check-cfa-2.c | 13 + .../gcc.target/riscv/stack-check-prologue-1.c | 9 + .../riscv/stack-check-prologue-10.c | 11 + .../riscv/stack-check-prologue-11.c | 11 + .../riscv/stack-check-prologue-12.c | 15 ++ .../riscv/stack-check-prologue-13.c | 20 ++ .../riscv/stack-check-prologue-14.c | 24 ++ .../riscv/stack-check-prologue-15.c | 23 ++ .../gcc.target/riscv/stack-check-prologue-2.c | 10 + .../gcc.target/riscv/stack-check-prologue-3.c | 11 + .../gcc.target/riscv/stack-check-prologue-4.c | 11 + .../gcc.target/riscv/stack-check-prologue-5.c | 11 + .../gcc.target/riscv/stack-check-prologue-6.c | 11 + .../gcc.target/riscv/stack-check-prologue-7.c | 11 + .../gcc.target/riscv/stack-check-prologue-8.c | 10 + .../gcc.target/riscv/stack-check-prologue-9.c | 11 + .../gcc.target/riscv/stack-check-prologue.h | 5 + gcc/testsuite/lib/target-supports.exp | 6 +- 27 files changed, 504 insertions(+), 40 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-12.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-13.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-cfa-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-cfa-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-12.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-13.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-14.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-15.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue.h diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 89fc8966654..292d190f319 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7950,6 +7950,191 @@ get_multi_push_fpr_mask (unsigned max_fprs_push) return mask_fprs_push; } +/* Allocate SIZE bytes of stack space using TEMP1 as a scratch register. + If SIZE is not large enough to require a probe this function will only + adjust the stack. + + We emit barriers after each stack adjustment to prevent optimizations from + breaking the invariant that we never drop the stack more than a page. This + invariant is needed to make it easier to correctly handle asynchronous + events, e.g. if we were to allow the stack to be dropped by more than a page + and then have multiple probes up and we take a signal somewhere in between + then the signal handler doesn't know the state of the stack and can make no + assumptions about which pages have been probed. */ + +static void +riscv_allocate_and_probe_stack_space (rtx temp1, HOST_WIDE_INT size) +{ + HOST_WIDE_INT guard_size + = 1 << param_stack_clash_protection_guard_size; + HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD; + HOST_WIDE_INT byte_sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; + HOST_WIDE_INT min_probe_threshold = guard_size - guard_used_by_caller; + rtx insn; + + /* We should always have a positive probe threshold. */ + gcc_assert (min_probe_threshold > 0); + + /* If SIZE is not large enough to require probing, just adjust the stack and + exit. */ + if (known_lt (size, min_probe_threshold) + || !flag_stack_clash_protection) + { + if (flag_stack_clash_protection) + { + if (known_eq (cfun->machine->frame.total_size, 0)) + dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false); + else + dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true); + } + + if (SMALL_OPERAND (-size)) + { + insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-size)); + RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; + } + else if (SUM_OF_TWO_S12_ALGN (-size)) + { + HOST_WIDE_INT one, two; + riscv_split_sum_of_two_s12 (-size, &one, &two); + insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (one)); + RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; + insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (two)); + RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; + } + else + { + temp1 = riscv_force_temporary (temp1, GEN_INT (-size)); + emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, temp1)); + insn = plus_constant (Pmode, stack_pointer_rtx, -size); + insn = gen_rtx_SET (stack_pointer_rtx, insn); + riscv_set_frame_expr (insn); + } + + /* We must have allocated the remainder of the stack frame. + Emit a stack tie if we have a frame pointer so that the + allocation is ordered WRT fp setup and subsequent writes + into the frame. */ + if (frame_pointer_needed) + riscv_emit_stack_tie (hard_frame_pointer_rtx); + + return; + } + + gcc_assert (multiple_p (size, byte_sp_alignment)); + + if (dump_file) + fprintf (dump_file, + "Stack clash prologue: " HOST_WIDE_INT_PRINT_DEC + " bytes, probing will be required.\n", size); + + /* Round size to the nearest multiple of guard_size, and calculate the + residual as the difference between the original size and the rounded + size. */ + HOST_WIDE_INT rounded_size = ROUND_DOWN (size, guard_size); + HOST_WIDE_INT residual = size - rounded_size; + + /* We can handle a small number of allocations/probes inline. Otherwise + punt to a loop. */ + if (rounded_size <= STACK_CLASH_MAX_UNROLL_PAGES * guard_size) + { + temp1 = riscv_force_temporary (temp1, gen_int_mode (guard_size, Pmode)); + for (HOST_WIDE_INT i = 0; i < rounded_size; i += guard_size) + { + emit_insn (gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, temp1)); + insn = plus_constant (Pmode, stack_pointer_rtx, -guard_size); + insn = gen_rtx_SET (stack_pointer_rtx, insn); + riscv_set_frame_expr (insn); + emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, + guard_used_by_caller)); + emit_insn (gen_blockage ()); + } + dump_stack_clash_frame_info (PROBE_INLINE, size != rounded_size); + } + else + { + /* Compute the ending address. */ + temp1 = riscv_force_temporary (temp1, gen_int_mode (rounded_size, Pmode)); + insn = emit_insn (gen_sub3_insn (temp1, stack_pointer_rtx, temp1)); + + if (!frame_pointer_needed) + { + /* We want the CFA independent of the stack pointer for the + duration of the loop. */ + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (Pmode, temp1, rounded_size)); + RTX_FRAME_RELATED_P (insn) = 1; + } + + /* Allocate and probe the stack. */ + + rtx temp2 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP2_REGNUM); + temp2 = riscv_force_temporary (temp2, gen_int_mode (guard_size, Pmode)); + + /* Loop. */ + rtx label = gen_label_rtx (); + emit_label (label); + + emit_insn (gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, temp2)); + emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, + guard_used_by_caller)); + emit_insn (gen_blockage ()); + + /* Check if the stack pointer is at the ending address. */ + riscv_expand_conditional_branch (label, NE, stack_pointer_rtx, temp1); + JUMP_LABEL (get_last_insn ()) = label; + + emit_insn (gen_blockage ()); + + /* Now reset the CFA register if needed. */ + if (!frame_pointer_needed) + { + insn = get_last_insn (); + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (Pmode, stack_pointer_rtx, rounded_size)); + RTX_FRAME_RELATED_P (insn) = 1; + } + + dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size); + } + + /* Handle any residuals. Residuals of at least MIN_PROBE_THRESHOLD have to + be probed. This maintains the requirement that each page is probed at + least once. For initial probing we probe only if the allocation is + more than GUARD_SIZE - buffer, and below the saved registers we probe + if the amount is larger than buffer. GUARD_SIZE - buffer + buffer == + GUARD_SIZE. This works that for any allocation that is large enough to + trigger a probe here, we'll have at least one, and if they're not large + enough for this code to emit anything for them, The page would have been + probed by the saving of FP/LR either by this function or any callees. If + we don't have any callees then we won't have more stack adjustments and so + are still safe. */ + if (residual) + { + gcc_assert (guard_used_by_caller + byte_sp_alignment <= size); + + temp1 = riscv_force_temporary (temp1, gen_int_mode (residual, Pmode)); + emit_insn (gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, temp1)); + insn = plus_constant (Pmode, stack_pointer_rtx, -residual); + insn = gen_rtx_SET (stack_pointer_rtx, insn); + riscv_set_frame_expr (insn); + if (residual >= min_probe_threshold) + { + if (dump_file) + fprintf (dump_file, + "Stack clash prologue residuals: " + HOST_WIDE_INT_PRINT_DEC " bytes, probing will be required." + "\n", residual); + + emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, + guard_used_by_caller)); + emit_insn (gen_blockage ()); + } + } +} + /* Expand the "prologue" pattern. */ void @@ -8112,42 +8297,14 @@ riscv_expand_prologue (void) return; } - if (SMALL_OPERAND (-constant_frame)) - { - insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-constant_frame)); - RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; - } - else if (SUM_OF_TWO_S12_ALGN (-constant_frame)) - { - HOST_WIDE_INT one, two; - riscv_split_sum_of_two_s12 (-constant_frame, &one, &two); - insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (one)); - RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; - insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (two)); - RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; - } + riscv_allocate_and_probe_stack_space (RISCV_PROLOGUE_TEMP (Pmode), constant_frame); + } + else if (flag_stack_clash_protection) + { + if (known_eq (frame->total_size, 0)) + dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false); else - { - riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (-constant_frame)); - emit_insn (gen_add3_insn (stack_pointer_rtx, - stack_pointer_rtx, - RISCV_PROLOGUE_TEMP (Pmode))); - - /* Describe the effect of the previous instructions. */ - insn = plus_constant (Pmode, stack_pointer_rtx, -constant_frame); - insn = gen_rtx_SET (stack_pointer_rtx, insn); - riscv_set_frame_expr (insn); - } - - /* We must have allocated the remainder of the stack frame. - Emit a stack tie if we have a frame pointer so that the - allocation is ordered WRT fp setup and subsequent writes - into the frame. */ - if (frame_pointer_needed) - riscv_emit_stack_tie (hard_frame_pointer_rtx); + dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true); } } @@ -9894,6 +10051,23 @@ riscv_option_override (void) riscv_stack_protector_guard_offset = offs; } + int guard_size = param_stack_clash_protection_guard_size; + + /* Enforce that interval is the same size as guard size so the mid-end does + the right thing. */ + SET_OPTION_IF_UNSET (&global_options, &global_options_set, + param_stack_clash_protection_probe_interval, + guard_size); + + /* The maybe_set calls won't update the value if the user has explicitly set + one. Which means we need to validate that probing interval and guard size + are equal. */ + int probe_interval + = param_stack_clash_protection_probe_interval; + if (guard_size != probe_interval) + error ("stack clash guard size %<%d%> must be equal to probing interval " + "%<%d%>", guard_size, probe_interval); + SET_OPTION_IF_UNSET (&global_options, &global_options_set, param_sched_pressure_algorithm, SCHED_PRESSURE_MODEL); diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 6f040011864..9670c7df8f7 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -1260,4 +1260,12 @@ extern void riscv_remove_unneeded_save_restore_calls (void); /* Check TLS Descriptors mechanism is selected. */ #define TARGET_TLSDESC (riscv_tls_dialect == TLS_DESCRIPTORS) +/* This value is the amount of bytes a caller is allowed to drop the stack + before probing has to be done for stack clash protection. */ +#define STACK_CLASH_CALLER_GUARD 1024 + +/* This value controls how many pages we manually unroll the loop for when + generating stack clash probes. */ +#define STACK_CLASH_MAX_UNROLL_PAGES 4 + #endif /* ! GCC_RISCV_H */ diff --git a/gcc/testsuite/gcc.dg/params/blocksort-part.c b/gcc/testsuite/gcc.dg/params/blocksort-part.c index cc15223c0de..72cd5da322c 100644 --- a/gcc/testsuite/gcc.dg/params/blocksort-part.c +++ b/gcc/testsuite/gcc.dg/params/blocksort-part.c @@ -1,4 +1,4 @@ -/* { dg-skip-if "AArch64 does not support these bounds." { aarch64*-*-* } { "--param stack-clash-protection-*" } } */ +/* { dg-skip-if "RISC-V and AArch64 do not support these bounds." { riscv*-*-* aarch64*-*-* } { "--param stack-clash-protection-*" } } */ /* { dg-skip-if "For 32-bit hosts such param is too much and even for 64-bit might require hundreds of GB of RAM" { *-*-* } { "--param min-nondebug-insn-uid=1073741824" } } */ /*-------------------------------------------------------------*/ diff --git a/gcc/testsuite/gcc.dg/pr82788.c b/gcc/testsuite/gcc.dg/pr82788.c index 41c442f61a6..f5cb333f619 100644 --- a/gcc/testsuite/gcc.dg/pr82788.c +++ b/gcc/testsuite/gcc.dg/pr82788.c @@ -1,5 +1,5 @@ /* { dg-do run } */ /* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-probe-interval=10 --param stack-clash-protection-guard-size=12" } */ /* { dg-require-effective-target supports_stack_clash_protection } */ -/* { dg-skip-if "AArch64 does not support this interval." { aarch64*-*-* } } */ +/* { dg-skip-if "RISC-V and AArch64 do not support this interval." { riscv*-*-* aarch64*-*-* } } */ int main() { int a[1442]; return 0;} diff --git a/gcc/testsuite/gcc.dg/stack-check-6.c b/gcc/testsuite/gcc.dg/stack-check-6.c index fe75612b737..50eb1924602 100644 --- a/gcc/testsuite/gcc.dg/stack-check-6.c +++ b/gcc/testsuite/gcc.dg/stack-check-6.c @@ -48,7 +48,7 @@ f7 (void) /* { dg-final { scan-rtl-dump-times "Stack clash inline probes" 2 "pro_and_epilogue" } } */ /* { dg-final { scan-rtl-dump-times "Stack clash probe loop" 2 "pro_and_epilogue" } } */ -/* { dg-final { scan-rtl-dump-times "Stack clash residual allocation in prologue" 4 "pro_and_epilogue" } } */ +/* { dg-final { scan-rtl-dump-times "Stack clash residual allocation in prologue" 4 "pro_and_epilogue" { target { ! riscv*-*-* } } } } */ /* { dg-final { scan-rtl-dump-times "Stack clash not noreturn" 4 "pro_and_epilogue" } } */ /* { dg-final { scan-rtl-dump-times "Stack clash no frame pointer needed" 4 "pro_and_epilogue" { target { ! frame_pointer_for_non_leaf } } } } */ diff --git a/gcc/testsuite/gcc.dg/stack-check-6a.c b/gcc/testsuite/gcc.dg/stack-check-6a.c index 68dd9bc48a0..8c6b5367afc 100644 --- a/gcc/testsuite/gcc.dg/stack-check-6a.c +++ b/gcc/testsuite/gcc.dg/stack-check-6a.c @@ -5,7 +5,7 @@ /* { dg-options "-O2 -fstack-clash-protection -fdump-rtl-pro_and_epilogue -fno-optimize-sibling-calls --param stack-clash-protection-probe-interval=12 --param stack-clash-protection-guard-size=16" } */ /* { dg-require-effective-target supports_stack_clash_protection } */ /* { dg-skip-if "" { *-*-* } { "-fstack-protector*" } { "" } } */ -/* { dg-skip-if "" { aarch64*-*-* } } */ +/* { dg-skip-if "" { riscv*-*-* aarch64*-*-* } } */ #include "stack-check-6.c" diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-12.c b/gcc/testsuite/gcc.target/riscv/stack-check-12.c new file mode 100644 index 00000000000..ceb9acc3c40 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-12.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector --param stack-clash-protection-guard-size=16" } */ +/* { dg-skip-if "" { *-*-* } { "-g"} } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +typedef unsigned __attribute__((mode(DI))) uint64_t; + +extern void arf (uint64_t *, uint64_t *); +void +frob () +{ + uint64_t num[10000]; + uint64_t den[10000]; + arf (den, num); +} + +/* This verifies that the scheduler did not break the dependencies + by adjusting the offsets within the probe and that the scheduler + did not reorder around the stack probes. */ +/* { dg-final { scan-assembler-times "li\\tt0,65536" 1 } } */ +/* { dg-final { scan-assembler-times "sub\\tsp,sp,t0\\n\\tsd\\tzero,1024\\(sp\\)" 2 } } */ +/* There is some residual allocation, but we don't care about that. Only that it's not probed. */ +/* { dg-final { scan-assembler-times "sd\\tzero," 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-13.c b/gcc/testsuite/gcc.target/riscv/stack-check-13.c new file mode 100644 index 00000000000..abd8a32b712 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-13.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection -fno-asynchronous-unwind-tables -fno-unwind-tables" } */ +/* { dg-skip-if "" { *-*-* } { "-g"} } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define ARG32(X) X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X +#define ARG384(X) ARG32(X),ARG32(X),ARG32(X),ARG32(X),ARG32(X),ARG32(X), ARG32(X),ARG32(X),ARG32(X),ARG32(X),ARG32(X),ARG32(X) +void out1(ARG384(__int128)); +int t1(int); + +int t3(int x) +{ + if (x < 1000) + return t1 (x) + 1; + + out1 (ARG384(1)); + return 0; +} + + + +/* This test creates a large (> 1k) outgoing argument area that needs + to be probed. We don't test the exact size of the space or the + exact offset to make the test a little less sensitive to trivial + output changes. */ +/* { dg-final { scan-assembler-times "sub\\tsp,sp,t0\\n\\tsd\\tzero,1024\\(sp\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-cfa-1.c b/gcc/testsuite/gcc.target/riscv/stack-check-cfa-1.c new file mode 100644 index 00000000000..60b01578692 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-cfa-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection -funwind-tables -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 128*1024 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {\.cfi_def_cfa [0-9]+, 131072} 1 } } */ +/* { dg-final { scan-assembler-times {\.cfi_def_cfa_register 2} 1 } } */ +/* { dg-final { scan-assembler-times {\.cfi_def_cfa_offset 0} 1 } } */ + +/* Checks that the CFA notes are correct for every sp adjustment. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-cfa-2.c b/gcc/testsuite/gcc.target/riscv/stack-check-cfa-2.c new file mode 100644 index 00000000000..9d36a302222 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-cfa-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection -funwind-tables -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 80*1024 + 512 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {\.cfi_def_cfa [0-9]+, 81920} 1 } } */ +/* { dg-final { scan-assembler-times {\.cfi_def_cfa_register 2} 1 } } */ +/* { dg-final { scan-assembler-times {\.cfi_def_cfa_offset 82432} 1 } } */ +/* { dg-final { scan-assembler-times {\.cfi_def_cfa_offset 0} 1 } } */ + +/* Checks that the CFA notes are correct for every sp adjustment. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-1.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-1.c new file mode 100644 index 00000000000..9f2c527a5ed --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 128 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-not "sd\tzero," } } */ +/* SIZE is smaller than guard-size - 1Kb so no probe expected. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-10.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-10.c new file mode 100644 index 00000000000..fd171c30f89 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-10.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE (6 * 4 * 1024) + (1 * 3 * 1024) + 512 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 2 } } */ + +/* SIZE is more than 4x guard-size and remainder larger than guard-size - 1Kb, + 1 probe expected in a loop and 1 residual probe. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-11.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-11.c new file mode 100644 index 00000000000..ebe3b139eb0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-11.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE (6 * 4 * 1024) + (1 * 2 * 1024) +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* SIZE is more than 4x guard-size and remainder larger than guard-size - 1Kb, + 1 probe expected in a loop and 1 residual probe. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-12.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-12.c new file mode 100644 index 00000000000..2a001ea8b1f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-12.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +void +f (void) +{ + volatile int x[16384 + 1000]; + x[0] = 0; +} + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* SIZE is more than 1 guard-size, but only one 64KB page is used, expect only 1 + probe. Leaf function and omitting leaf pointers. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-13.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-13.c new file mode 100644 index 00000000000..d97f69a943f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-13.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +void h (void) __attribute__ ((noreturn)); + +void +f (void) +{ + volatile int x[16384 + 1000]; + x[30]=0; + h (); +} + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ +/* { dg-final { scan-assembler-times {sw\tzero,120\(sp\)} 1 } } */ + +/* SIZE is more than 1 guard-size, but only one 64KB page is used, expect only 1 + probe. Leaf function and omitting leaf pointers, tail call to noreturn which + may only omit an epilogue and not a prologue. Checking for LR saving. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-14.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-14.c new file mode 100644 index 00000000000..bd263fbbd80 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-14.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +void h (void) __attribute__ ((noreturn)); + +void +f (void) +{ + volatile int x[16384 + 1000]; + if (x[0]) + h (); + x[345] = 1; + h (); +} + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ +/* { dg-final { scan-assembler-times {sd\tra,8\(sp\)} 1 } } */ + +/* SIZE is more than 1 guard-size, two 64k pages used, expect only 1 explicit + probe at 1024 and one implicit probe due to LR being saved. Leaf function + and omitting leaf pointers, tail call to noreturn which may only omit an + epilogue and not a prologue and control flow in between. Checking for + LR saving. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-15.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-15.c new file mode 100644 index 00000000000..f175e6f5b8f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-15.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +void g (volatile int *x) ; +void h (void) __attribute__ ((noreturn)); + +void +f (void) +{ + volatile int x[16384 + 1000]; + g (x); + h (); +} + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ +/* { dg-final { scan-assembler-times {sd\tra,8\(sp\)} 1 } } */ + +/* SIZE is more than 1 guard-size, two 64k pages used, expect only 1 explicit + probe at 1024 and one implicit probe due to LR being saved. Leaf function + and omitting leaf pointers, normal function call followed by a tail call to + noreturn which may only omit an epilogue and not a prologue and control flow + in between. Checking for LR saving. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-2.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-2.c new file mode 100644 index 00000000000..9c78b1ebaf1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 2 * 1024 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-not "sd\tzero," } } */ + +/* SIZE is smaller than guard-size - 1Kb so no probe expected. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-3.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-3.c new file mode 100644 index 00000000000..2c7e55acae6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 3 * 1024 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times "sd\tzero," 1 } } */ + +/* SIZE is exactly guard-size - 1Kb, boundary condition so 1 probe expected. +*/ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-4.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-4.c new file mode 100644 index 00000000000..506ea7b19c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-4.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 3 * 1024 + 512 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* SIZE is more than guard-size - 1Kb and remainder is less than 1kB, + 1 probe expected. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-5.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-5.c new file mode 100644 index 00000000000..4c50a2a47a2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-5.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 4 * 1024 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* SIZE is more than guard-size - 1Kb and remainder is zero, + 1 probe expected, boundary condition. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-6.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-6.c new file mode 100644 index 00000000000..db39ecdc39f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-6.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 5 * 1024 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* SIZE is more than guard-size - 1Kb and remainder is equal to 1kB, + 1 probe expected. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-7.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-7.c new file mode 100644 index 00000000000..b394849136d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-7.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 7 * 1024 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 2 } } */ + +/* SIZE is more than 1x guard-size and remainder equal than guard-size - 1Kb, + 2 probe expected, unrolled, no loop. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-8.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-8.c new file mode 100644 index 00000000000..6366cacc520 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-8.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 8 * 1024 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 2 } } */ + +/* SIZE is more than 2x guard-size and no remainder, unrolled, no loop. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-9.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-9.c new file mode 100644 index 00000000000..5e65750b9e8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-9.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#define SIZE 6 * 4 * 1024 +#include "stack-check-prologue.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* SIZE is more than 4x guard-size and no remainder, 1 probe expected in a loop + and no residual probe. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue.h b/gcc/testsuite/gcc.target/riscv/stack-check-prologue.h new file mode 100644 index 00000000000..b7e06aedb81 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue.h @@ -0,0 +1,5 @@ +int f_test (int x) +{ + char arr[SIZE]; + return arr[x]; +} diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index daa0c75d2bc..3d7a4691624 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -12718,7 +12718,7 @@ proc check_effective_target_supports_stack_clash_protection { } { if { [istarget x86_64-*-*] || [istarget i?86-*-*] || [istarget powerpc*-*-*] || [istarget rs6000*-*-*] || [istarget aarch64*-**] || [istarget s390*-*-*] - || [istarget loongarch64*-**] } { + || [istarget loongarch64*-**] || [istarget riscv64*-**] } { return 1 } return 0 @@ -12778,6 +12778,10 @@ proc check_effective_target_caller_implicit_probes { } { return 1; } + if { [istarget riscv64*-*-*] } { + return 1; + } + if { [istarget loongarch64*-*-*] } { return 1; } From patchwork Wed Jul 24 18:00:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raphael Moreira Zinsly X-Patchwork-Id: 1964455 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ventanamicro.com header.i=@ventanamicro.com header.a=rsa-sha256 header.s=google header.b=MVHReUXW; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WThdr1G5bz1yXx for ; Thu, 25 Jul 2024 04:01:04 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4C5033861031 for ; Wed, 24 Jul 2024 18:01:02 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id ECAB7385828E for ; Wed, 24 Jul 2024 18:00:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org ECAB7385828E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=ventanamicro.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org ECAB7385828E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844036; cv=none; b=HWs7HbpzQAwQqPoaiuIpf8iUiDkM8Ax8zJtWzD0a2xlHGljyA5oEWX/phF8vP/TtsX+awvDlJgz5FBU+ri/qFrHrQqZQX9caDUhV/FYZ2TiN+Ij21WmtbBA2jZhlrWbLhAeMehS6DzHphCeX7FMSpsX6YKtyGxp4CbhTmseX3wg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844036; c=relaxed/simple; bh=1U83GjXNem+fujSJ6/ea61MxH1ym7nvaTrcCBkfHac8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=I72AMt7Rcm5fZdN2pp8VwbL8WaEkLAm9Ucp4YZSAgCE1bhDGP66TsjT/9VHo9du3kZcgy53D6xuPA2VAzs2OYF2uj5+ZqAFefwRB64pAkuRP2kCdUqsU8djlvqj2h+U7RGzNJBz/+fhLZfQnbH4Jb5jxQqi3E+TnYMMIkOj2J9c= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1fd6ed7688cso345695ad.3 for ; Wed, 24 Jul 2024 11:00:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1721844031; x=1722448831; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NbNMmJZRkjp1mf77SBveoaH+l/oiSZuOehV0rA1NoCc=; b=MVHReUXWezjV+BfzVO94u0q8GqLIL8xNzetSfh0BB26PN8HMe28kmmVrRlNYWIyK+D fW/ODMtLFM907PhWImj/PLIWzaohcZfWfo71+g9bnSnVYFie+TmweglDPrdaerfBI2Hj OIFsNNWaQcQa8NT1RXDBaoc52fWIip1fsJpl85ES7u8uQDrqC3D95eHFAI2s1VNbBxzk Ye/lVFNEAB3jfFBsCzq8di40iLQCmEpcByfS3rQCFeH4inrK/h50YZtBOWhrERaThQjv sSz3tbELiGKWNGnMyQ/tfA42gyqbY40uUbyUd3jE1/53oo48AvSTMrpZwmWgAEOybhjc ZEyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721844031; x=1722448831; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NbNMmJZRkjp1mf77SBveoaH+l/oiSZuOehV0rA1NoCc=; b=DXH9DeCpyAxj0UfPcn377FmskImYNqJ0mE6ErvvyrIPBcomMTG9a0WJE3WGkGMBdF4 ze/pWcUYpcWe8ZhElO0d1e/HOH3CdB1gJ3eS0C2O52vmkKGwZNFq3KpFkOMUH1bqFGLU V1JGc+xSceOjfkfhkSKnPRGA5lamFvCb1Labb//Z+q/SHrDJ5d1E5Mo/mAlZbUqdHcHT EPFqIBMAppf+3PE4LPlNbf/1KDjqZVT8DxQPvcH33PrAml8Yr+EP7gPTLRttm1g72oou mmZCQl72vR8rdQ+fgfesXRuHuDKuTOGSMpx7gXztJwIWBDRrQNLjoT18CccEx5wmS0Jr ZDPQ== X-Gm-Message-State: AOJu0YzoRjw9ZH773ds/nU0mJ//zKzWgLda1zKSKh0UjqcSNPG1BMw3T /DvVnkD4SJvF9rlNXZyBrEi6zNnY98TpiIm0l1jKG+zWL5mFuZSvOOSUlt1qlqoPEUt64Y9DHXR x X-Google-Smtp-Source: AGHT+IGe8O1N5JpTJGJlIaxrmMWVSUpUZwZWworSRgb/7VNPJWXD6mKnCNnrFA7TugWeKm9B6p8Fng== X-Received: by 2002:a17:903:22cd:b0:1fc:6cf5:df4b with SMTP id d9443c01a7336-1fed38da461mr4773775ad.49.1721844031514; Wed, 24 Jul 2024 11:00:31 -0700 (PDT) Received: from marvin.dc1.ventanamicro.com ([189.4.72.88]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fd6f4713f8sm97261705ad.268.2024.07.24.11.00.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Jul 2024 11:00:31 -0700 (PDT) From: Raphael Moreira Zinsly To: gcc-patches@gcc.gnu.org Cc: jlaw@ventanamicro.com, Raphael Moreira Zinsly Subject: [PATCH 4/5] RISC-V: Add support to vector stack-clash protection Date: Wed, 24 Jul 2024 15:00:12 -0300 Message-ID: <5875f10117079a9484b0ad0d439bbfe7210c5d85.1721681845.git.rzinsly@ventanamicro.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, LIKELY_SPAM_BODY, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK 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: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Adds basic support to vector stack-clash protection using a loop to do the probing and stack adjustments. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_allocate_and_probe_stack_loop): New function. (riscv_v_adjust_scalable_frame): Add stack-clash protection support. (riscv_allocate_and_probe_stack_space): Move the probe loop implementation to riscv_allocate_and_probe_stack_loop. * config/riscv/riscv.h: Define RISCV_STACK_CLASH_VECTOR_CFA_REGNUM. gcc/testsuite/ChangeLog: * gcc.target/riscv/stack-check-cfa-3.c: New test. * gcc.target/riscv/stack-check-prologue-16.c: New test. * gcc.target/riscv/struct_vect_24.c: New test. --- gcc/config/riscv/riscv.cc | 99 +++++++++++++++---- gcc/config/riscv/riscv.h | 2 + .../gcc.target/riscv/stack-check-cfa-3.c | 13 +++ .../riscv/stack-check-prologue-16.c | 30 ++++++ .../gcc.target/riscv/struct_vect_24.c | 47 +++++++++ 5 files changed, 170 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-prologue-16.c create mode 100644 gcc/testsuite/gcc.target/riscv/struct_vect_24.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 292d190f319..69c0e07f4c5 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7897,6 +7897,35 @@ static const code_for_push_pop_t code_for_push_pop[ZCMP_MAX_GRP_SLOTS][ZCMP_OP_N code_for_gpr_multi_popret_up_to_s11, code_for_gpr_multi_popretz_up_to_s11}}; +/* Set a probe loop for stack clash protection. */ +static void +riscv_allocate_and_probe_stack_loop (rtx tmp, enum rtx_code code, + rtx op0, rtx op1, bool vector, + HOST_WIDE_INT offset) +{ + tmp = riscv_force_temporary (tmp, gen_int_mode (offset, Pmode)); + + /* Loop. */ + rtx label = gen_label_rtx (); + emit_label (label); + + /* Allocate and probe stack. */ + emit_insn (gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, tmp)); + emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, + STACK_CLASH_CALLER_GUARD)); + emit_insn (gen_blockage ()); + + /* Adjust the remaining vector length. */ + if (vector) + emit_insn (gen_sub3_insn (op0, op0, tmp)); + + /* Branch if there's still more bytes to probe. */ + riscv_expand_conditional_branch (label, code, op0, op1); + JUMP_LABEL (get_last_insn ()) = label; + + emit_insn (gen_blockage ()); +} + /* Adjust scalable frame of vector for prologue && epilogue. */ static void @@ -7909,6 +7938,49 @@ riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue) riscv_legitimize_poly_move (Pmode, adjust_size, tmp, gen_int_mode (offset, Pmode)); + /* If doing stack clash protection then we use a loop to allocate and probe + the stack. */ + if (flag_stack_clash_protection && !epilogue) + { + HOST_WIDE_INT min_probe_threshold + = (1 << param_stack_clash_protection_guard_size) - STACK_CLASH_CALLER_GUARD; + + if (!frame_pointer_needed) + { + /* This is done to provide unwinding information for the stack + adjustments we're about to do, however to prevent the optimizers + from removing the S0 move and leaving the CFA note (which would be + very wrong) we tie the old and new stack pointer together. + The tie will expand to nothing but the optimizers will not touch + the instruction. */ + insn = get_last_insn (); + rtx stack_ptr_copy = gen_rtx_REG (Pmode, RISCV_STACK_CLASH_VECTOR_CFA_REGNUM); + emit_move_insn (stack_ptr_copy, stack_pointer_rtx); + riscv_emit_stack_tie (stack_ptr_copy); + + /* We want the CFA independent of the stack pointer for the + duration of the loop. */ + add_reg_note (insn, REG_CFA_DEF_CFA, stack_ptr_copy); + RTX_FRAME_RELATED_P (insn) = 1; + } + + riscv_allocate_and_probe_stack_loop (tmp, GE, adjust_size, tmp, true, + min_probe_threshold); + + /* Allocate the residual. */ + insn = emit_insn (gen_sub3_insn (target, target, adjust_size)); + + /* Now reset the CFA register if needed. */ + if (!frame_pointer_needed) + { + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (Pmode, stack_pointer_rtx, -offset)); + RTX_FRAME_RELATED_P (insn) = 1; + } + + return; + } + if (epilogue) insn = gen_add3_insn (target, target, adjust_size); else @@ -8056,8 +8128,9 @@ riscv_allocate_and_probe_stack_space (rtx temp1, HOST_WIDE_INT size) else { /* Compute the ending address. */ - temp1 = riscv_force_temporary (temp1, gen_int_mode (rounded_size, Pmode)); - insn = emit_insn (gen_sub3_insn (temp1, stack_pointer_rtx, temp1)); + rtx temp2 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP2_REGNUM); + temp2 = riscv_force_temporary (temp2, gen_int_mode (rounded_size, Pmode)); + insn = emit_insn (gen_sub3_insn (temp2, stack_pointer_rtx, temp2)); if (!frame_pointer_needed) { @@ -8068,25 +8141,9 @@ riscv_allocate_and_probe_stack_space (rtx temp1, HOST_WIDE_INT size) RTX_FRAME_RELATED_P (insn) = 1; } - /* Allocate and probe the stack. */ - - rtx temp2 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP2_REGNUM); - temp2 = riscv_force_temporary (temp2, gen_int_mode (guard_size, Pmode)); - - /* Loop. */ - rtx label = gen_label_rtx (); - emit_label (label); - - emit_insn (gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, temp2)); - emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, - guard_used_by_caller)); - emit_insn (gen_blockage ()); - - /* Check if the stack pointer is at the ending address. */ - riscv_expand_conditional_branch (label, NE, stack_pointer_rtx, temp1); - JUMP_LABEL (get_last_insn ()) = label; - - emit_insn (gen_blockage ()); + /* This allocates and probes the stack. */ + riscv_allocate_and_probe_stack_loop (temp1, NE, stack_pointer_rtx, temp2, + false, guard_size); /* Now reset the CFA register if needed. */ if (!frame_pointer_needed) diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 9670c7df8f7..0432beb81e0 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -429,6 +429,8 @@ ASM_MISA_SPEC #define RISCV_PROLOGUE_TEMP2_REGNUM (GP_TEMP_FIRST + 1) #define RISCV_PROLOGUE_TEMP2(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP2_REGNUM) +#define RISCV_STACK_CLASH_VECTOR_CFA_REGNUM (GP_TEMP_FIRST + 4) + #define RISCV_CALL_ADDRESS_TEMP_REGNUM (GP_TEMP_FIRST + 1) #define RISCV_CALL_ADDRESS_TEMP(MODE) \ gen_rtx_REG (MODE, RISCV_CALL_ADDRESS_TEMP_REGNUM) diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c b/gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c new file mode 100644 index 00000000000..cc0d54ed7c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -fstack-clash-protection -funwind-tables -fno-stack-protector" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +#include "stack-check-prologue-16.c" + +/* Checks that the CFA notes are correct for every sp adjustment, but we also + need to make sure we can unwind correctly before the frame is set up. So + check that we're emitting s0 with a copy of sp an setting the CFA there. */ + +/* { dg-final { scan-assembler-times {mv\ts1,sp} 1 } } */ +/* { dg-final { scan-assembler-times {\.cfi_def_cfa [0-9]+, 0} 1 } } */ +/* { dg-final { scan-assembler-times {\.cfi_escape 0xf,0xa,0x72,0,0x92,0xa2,0x38,0,0x9,0xec,0x1e,0x22} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-prologue-16.c b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-16.c new file mode 100644 index 00000000000..c74dce04b23 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-prologue-16.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -fstack-clash-protection" } */ + +/* Invoke X (P##n) for n in [0, 7]. */ +#define REPEAT8(X, P) \ + X (P##0) X (P##1) X (P##2) X (P##3) X (P##4) X (P##5) X (P##6) X (P##7) + +/* Invoke X (n) for all octal n in [0, 39]. */ +#define REPEAT40(X) \ + REPEAT8 (X, 0) REPEAT8 (X, 1) REPEAT8 (X, 2) REPEAT8 (X, 3) REPEAT8 (X, 4) + +/* Expect vector work to be done, with spilling of vector registers. */ +void +f2 (int x[40][100], int *y) +{ + /* Try to force some spilling. */ +#define DECLARE(N) int y##N = y[N]; + REPEAT40 (DECLARE); +#pragma omp simd + for (int i = 0; i < 100; ++i) + { +#define INC(N) x[N][i] += y##N; + REPEAT40 (INC); + } +} + +/* Vector spill, requires probing as vector size is unknown at compile time. */ + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/struct_vect_24.c b/gcc/testsuite/gcc.target/riscv/struct_vect_24.c new file mode 100644 index 00000000000..7c0852f1a55 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/struct_vect_24.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -fstack-clash-protection -fno-stack-protector" } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-O2" "-Og" "-Os" "-Oz" "-funroll-loops"} } */ + +#include + +#define N 50 +#define S 2 * 4 * 1024 + +/* Invoke X (P##n) for n in [0, 9]. */ +#define REPEAT8(X, P) \ + X (P##0) X (P##1) X (P##2) X (P##3) X (P##4) X (P##5) X (P##6) X (P##7) \ + X (P##8) X (P##9) + +/* Invoke X (n) for all n in [0, 49]. */ +#define REPEAT50(X) \ + REPEAT8 (X, ) REPEAT8 (X, 1) REPEAT8 (X, 2) REPEAT8 (X, 3) REPEAT8 (X, 4) + + /* Try to force some spilling. */ +#define DECLARE(N) int src##N = src[N * 4]; +#define INC(N) dest[i] += src##N; + +#define TEST_LOOP(NAME, TYPE) \ + void __attribute__ ((noinline)) \ + NAME (TYPE *restrict dest, TYPE *restrict src) \ + { \ + REPEAT50 (DECLARE); \ + volatile char foo[S]; \ + foo[S-1]=1; \ + for (int i = 0; i < N; i++) \ + { \ + REPEAT50 (INC); \ + } \ + } + +#define TEST(NAME) \ + TEST_LOOP (NAME##_i32, int32_t) \ + TEST_LOOP (NAME##_i64, int64_t) + +TEST (test) + +/* Check the vectorized loop for stack clash probing. */ + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 6 } } */ +/* { dg-final { scan-assembler-times {bge\tt1,t0,.[^\\r\\n]*} 2 } } */ +/* { dg-final { scan-assembler-times {sub\s+t1,t1,t0} 2 } } */ From patchwork Wed Jul 24 18:00:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raphael Moreira Zinsly X-Patchwork-Id: 1964456 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ventanamicro.com header.i=@ventanamicro.com header.a=rsa-sha256 header.s=google header.b=FingnPx7; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WThfz0ryMz1yXx for ; Thu, 25 Jul 2024 04:02:02 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ECDD33861029 for ; Wed, 24 Jul 2024 18:02:00 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by sourceware.org (Postfix) with ESMTPS id 76BC93857000 for ; Wed, 24 Jul 2024 18:00:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 76BC93857000 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=ventanamicro.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 76BC93857000 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844039; cv=none; b=iDgnwURbeKtKWN7D6KsWhtZ0HfUCOCbkBb/saaSGxDA/OKITB65iJA3LRwANTKcaZnezAoOOvKyDhENF2EtvbwsFnLLeCAlEzZTIyBB3UD/8QtF0wV3S8WcAgySSdKqKuTcrgKcBNtePdt+iCgGLlEgtXHFzZfzu/RoOInJRT1g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721844039; c=relaxed/simple; bh=hKDVm6MWn3O7HulIig8FvyexAcDOM5ffyXc7c2Xh0pU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=HuoOQWqk6LL8Y4ccvAx536VtaAsdT0Kfvlnzfv+3gGM5ApfnjoAo0K7rbYIEjQUUVAN6KYJyvn8j8Z8PIBKmnGy1Cbb7duhCPJ7aZLFm6dyFeSktf0dO3NUzSAIi4bbIIdPTFVamwW14akcplmTfqRYT7V8tx1vpwLxXVTtDeTE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-1fc587361b6so374415ad.2 for ; Wed, 24 Jul 2024 11:00:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1721844034; x=1722448834; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Og4+Sh8ynKTs/3BkY+U3Ck20QVGOl5PObmBb7gUtVto=; b=FingnPx7UturikZAJ1TIb2dEsEotkCRMgLZP8jTXBT5+v2YEgrnTWqsfQR8DauLl9E L3eeKYXDNgbr21xXpjNrGgtrS5ogQEsg601zgbHmt2PLjqg4+gEF8hWpRPx5/l1z8tqj Mfb828xAt28xG7IsGm09CKG8ajwpGD007p6IeM30HicBUwkeANP6hJPLf3X5DnzQGgmo arzKI43XnYw0ennifNZrMuXIV2pKxg0bs4x2yPEKwRjlleYI+63/R2uwUWUc6cOlXrcJ C/S4yQnYDkh5i0LOaOOcWjKT1doG2xRbf1fGzMzXHevr/07zVESbY01XqknWzsieHyVB hTKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721844034; x=1722448834; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Og4+Sh8ynKTs/3BkY+U3Ck20QVGOl5PObmBb7gUtVto=; b=NvLJ/18ioArRcCOxgbMssrck5s5M/EweSksTAMWKiYF6DgxCCdMo59OZug0QjL04hr f/VzQOIBvJZ6wiA4pwX8hahqxNqWI2MfPa2sCM6tssvZX4xPy+5wv0qFDORE+cQR2Iu5 sQrxGPUjPlS+3WJ++uuuMjWSkkLdUbmWNYKeE5nTP2RJBJhVMQjo/U1Jya7laTkse2Ah TwbFXG3aEz7Dqe857IHvKUfsQtbxahpCKVk2y6LVnp7PHTrWIoz5IvCoYAngML6dJsiy yu4Xeq0DBT8PCFjEmN6k39sOBKz3mIQDRW2+s+J725M7NWmC2/W0Gocb3bLnIOFLbhfK mVkA== X-Gm-Message-State: AOJu0Yzd7x+uSd9UaDuY84DnkpQKAkIxKGVq93/7qy53CJjrVdqcW9Iw Bx1jssiL9oyA6oyEKZItncQ1LJm0NV301CgfH6mE/x5TWbPogzm9JGhGOOIaxHXi9Vs0IZqMBVl O X-Google-Smtp-Source: AGHT+IG9cbar4bTZ6rlxzGI2RFyo6I/5owzuL3b6AjbWaELtyudE41D0N436BkWkeNg4EBHZn1iw7Q== X-Received: by 2002:a17:903:41cd:b0:1fc:726e:15a6 with SMTP id d9443c01a7336-1fed38bdb22mr3199815ad.34.1721844033648; Wed, 24 Jul 2024 11:00:33 -0700 (PDT) Received: from marvin.dc1.ventanamicro.com ([189.4.72.88]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fd6f4713f8sm97261705ad.268.2024.07.24.11.00.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Jul 2024 11:00:33 -0700 (PDT) From: Raphael Moreira Zinsly To: gcc-patches@gcc.gnu.org Cc: jlaw@ventanamicro.com, Raphael Moreira Zinsly Subject: [PATCH 5/5] RISC-V: Enable stack clash in alloca Date: Wed, 24 Jul 2024 15:00:13 -0300 Message-ID: <1206ea55e95fef9c6a10cc8b9a5e85e2ec8d78bc.1721681845.git.rzinsly@ventanamicro.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK 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: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Add the TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE to riscv in order to enable stack clash protection when using alloca. The code and tests are the same used by aarch64. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_compute_frame_info): Update outgoing args size. (riscv_stack_clash_protection_alloca_probe_range): New. (TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE): New. * config/riscv/riscv.h (STACK_CLASH_MIN_BYTES_OUTGOING_ARGS): New. (STACK_DYNAMIC_OFFSET): New. gcc/testsuite/ChangeLog: * gcc.target/riscv/stack-check-14.c: New test. * gcc.target/riscv/stack-check-15.c: New test. * gcc.target/riscv/stack-check-alloca-1.c: New test. * gcc.target/riscv/stack-check-alloca-2.c: New test. * gcc.target/riscv/stack-check-alloca-3.c: New test. * gcc.target/riscv/stack-check-alloca-4.c: New test. * gcc.target/riscv/stack-check-alloca-5.c: New test. * gcc.target/riscv/stack-check-alloca-6.c: New test. * gcc.target/riscv/stack-check-alloca-7.c: New test. * gcc.target/riscv/stack-check-alloca-8.c: New test. * gcc.target/riscv/stack-check-alloca-9.c: New test. * gcc.target/riscv/stack-check-alloca-10.c: New test. * gcc.target/riscv/stack-check-alloca.h: New. --- gcc/config/riscv/riscv.cc | 17 +++++++++++++ gcc/config/riscv/riscv.h | 17 +++++++++++++ .../gcc.target/riscv/stack-check-14.c | 24 +++++++++++++++++++ .../gcc.target/riscv/stack-check-15.c | 21 ++++++++++++++++ .../gcc.target/riscv/stack-check-alloca-1.c | 15 ++++++++++++ .../gcc.target/riscv/stack-check-alloca-10.c | 13 ++++++++++ .../gcc.target/riscv/stack-check-alloca-2.c | 11 +++++++++ .../gcc.target/riscv/stack-check-alloca-3.c | 11 +++++++++ .../gcc.target/riscv/stack-check-alloca-4.c | 12 ++++++++++ .../gcc.target/riscv/stack-check-alloca-5.c | 12 ++++++++++ .../gcc.target/riscv/stack-check-alloca-6.c | 12 ++++++++++ .../gcc.target/riscv/stack-check-alloca-7.c | 12 ++++++++++ .../gcc.target/riscv/stack-check-alloca-8.c | 14 +++++++++++ .../gcc.target/riscv/stack-check-alloca-9.c | 13 ++++++++++ .../gcc.target/riscv/stack-check-alloca.h | 15 ++++++++++++ 15 files changed, 219 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-14.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-15.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack-check-alloca.h diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 69c0e07f4c5..a110e011766 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7245,6 +7245,10 @@ riscv_compute_frame_info (void) frame = &cfun->machine->frame; + /* Adjust the outgoing arguments size if required. Keep it in sync with what + the mid-end is doing. */ + crtl->outgoing_args_size = STACK_DYNAMIC_OFFSET (cfun); + /* In an interrupt function, there are two cases in which t0 needs to be used: 1, If we have a large frame, then we need to save/restore t0. We check for this before clearing the frame struct. @@ -11879,6 +11883,15 @@ riscv_c_mode_for_floating_type (enum tree_index ti) return default_mode_for_floating_type (ti); } +/* On riscv we have an ABI defined safe buffer. This constant is used to + determining the probe offset for alloca. */ + +static HOST_WIDE_INT +riscv_stack_clash_protection_alloca_probe_range (void) +{ + return STACK_CLASH_CALLER_GUARD; +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -12187,6 +12200,10 @@ riscv_c_mode_for_floating_type (enum tree_index ti) #define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \ riscv_vectorize_preferred_vector_alignment +#undef TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE +#define TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE \ + riscv_stack_clash_protection_alloca_probe_range + /* Mode switching hooks. */ #undef TARGET_MODE_EMIT diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 0432beb81e0..7f20190e960 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -1270,4 +1270,21 @@ extern void riscv_remove_unneeded_save_restore_calls (void); generating stack clash probes. */ #define STACK_CLASH_MAX_UNROLL_PAGES 4 +/* This value represents the minimum amount of bytes we expect the function's + outgoing arguments to be when stack-clash is enabled. */ +#define STACK_CLASH_MIN_BYTES_OUTGOING_ARGS 8 + +/* Allocate a minimum of STACK_CLASH_MIN_BYTES_OUTGOING_ARGS bytes for the + outgoing arguments if stack clash protection is enabled. This is essential + as the extra arg space allows us to skip a check in alloca. */ +#undef STACK_DYNAMIC_OFFSET +#define STACK_DYNAMIC_OFFSET(FUNDECL) \ + ((flag_stack_clash_protection \ + && cfun->calls_alloca \ + && known_lt (crtl->outgoing_args_size, \ + STACK_CLASH_MIN_BYTES_OUTGOING_ARGS)) \ + ? ROUND_UP (STACK_CLASH_MIN_BYTES_OUTGOING_ARGS, \ + STACK_BOUNDARY / BITS_PER_UNIT) \ + : (crtl->outgoing_args_size + STACK_POINTER_OFFSET)) + #endif /* ! GCC_RISCV_H */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-14.c b/gcc/testsuite/gcc.target/riscv/stack-check-14.c new file mode 100644 index 00000000000..8ca0488c468 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-14.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +int t1(int); + +int t2(int x) +{ + char *p = __builtin_alloca (2048); + x = t1 (x); + return p[x]; +} + + +/* This test has a constant sized alloca that is smaller than the + probe interval. Only one probe is required since the value is larger + than 1024 bytes but smaller than page size. + + The form can change quite a bit so we just check for one + probe without looking at the actual address. */ +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + + + diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-15.c b/gcc/testsuite/gcc.target/riscv/stack-check-15.c new file mode 100644 index 00000000000..a44b257ba75 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-15.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ + +int t1(int); + +int t2(int x) +{ + char *p = __builtin_alloca (x); + x = t1 (x); + return p[x]; +} + + +/* This test has a variable sized alloca. It requires 3 probes. + One in the loop, one for the residual, one for when it's < 1024 and one for + when it's not. + + The form can change quite a bit so we just check for three + probes without looking at the actual address. */ +/* { dg-final { scan-assembler-times {sd\tzero,} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-1.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-1.c new file mode 100644 index 00000000000..642840fb50c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE y +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 2 } } */ +/* { dg-final { scan-assembler-times {sd\tzero,0\(sp\)} 1 } } */ + +/* Dynamic alloca, expect loop, and 2 probes with 1kB offset and 1 at sp. + 1st probe is inside the loop for the full guard-size allocations, second + probe is for the case where residual is zero and the final probe for when + residiual is > 1024 bytes. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-10.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-10.c new file mode 100644 index 00000000000..11844aad748 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-10.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 127.5 * 3 * 1024 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 2 } } */ + +/* Large alloca of an amount which isn't a multiple of a guard-size, and + residiual is more than 1kB. Loop expected with one 1Kb probe offset and + one residual probe at offset 1kB. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-2.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-2.c new file mode 100644 index 00000000000..5c7a158adec --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 0 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-not {sd\tzero,} } } */ + +/* Alloca of 0 should emit no probes, boundary condition. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-3.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-3.c new file mode 100644 index 00000000000..a5db2679aef --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 100 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,8\(sp\)} 1 } } */ + +/* Alloca is less than 1kB, 1 probe expected at word offset. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-4.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-4.c new file mode 100644 index 00000000000..1841412ff36 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-4.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 1.5 * 1024 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* Alloca is more than 1kB, but less than guard-size, 1 probe expected at + 1kB offset. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-5.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-5.c new file mode 100644 index 00000000000..f8f9d944564 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-5.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 2 * 1024 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* Alloca is more than 1kB, but less than guard-size, 1 probe expected at + 1kB offset. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-6.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-6.c new file mode 100644 index 00000000000..d937e929d75 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-6.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 2.5 * 1024 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* Alloca is more than 1kB, but less than guard-size, 1 probe expected at 1kB + offset. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-7.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-7.c new file mode 100644 index 00000000000..cbb32f3157e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-7.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 3 * 1024 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* Alloca is exactly one guard-size, 1 probe expected at 1kB offset. + Boundary condition. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-8.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-8.c new file mode 100644 index 00000000000..3cc3450355b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-8.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 65 * 1024 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ +/* { dg-final { scan-assembler-times {sd\tzero,8\(sp\)} 1 } } */ + +/* Alloca is more than one guard-page, and residual is exactly 1Kb. 2 probes + expected. One at 1kB offset for the guard-size allocation and one at word + offset for the residual. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca-9.c b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-9.c new file mode 100644 index 00000000000..36466930e4e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca-9.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -fstack-clash-protection" } */ +/* { dg-require-effective-target supports_stack_clash_protection } */ +/* { dg-require-effective-target alloca } */ + +#define SIZE 127 * 3 * 1024 +#include "stack-check-alloca.h" + +/* { dg-final { scan-assembler-times {sd\tzero,1024\(sp\)} 1 } } */ + +/* Large alloca of a constant amount which is a multiple of a guard-size, + no residiual. Loop expected with one 1Kb probe offset and no residual probe + because residual is at compile time known to be zero. */ diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-alloca.h b/gcc/testsuite/gcc.target/riscv/stack-check-alloca.h new file mode 100644 index 00000000000..8c75f6c0f70 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack-check-alloca.h @@ -0,0 +1,15 @@ + +/* Avoid inclusion of alloca.h, unavailable on some systems. */ +#define alloca __builtin_alloca + +__attribute__((noinline, noipa)) +void g (char* ptr, int y) +{ + ptr[y] = '\0'; +} + +void f_caller (int y) +{ + char* pStr = alloca(SIZE); + g (pStr, y); +}