From patchwork Sat Jan 25 14:14:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans-Peter Nilsson X-Patchwork-Id: 1229235 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-518255-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=axis.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=ZKJ20BRl; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 484dL13MkVz9sP6 for ; Sun, 26 Jan 2020 01:14:15 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:from:to:cc:subject:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=VQRWNCDzbGmysQ4p ZIqs4VVQogZNt+M815nzjMfa7BzYDVcBEJELCICF9mpiLp+qYnDtQVdbaOMKkZfC 7bFuFRA7R7dDMjoEdoPndjZoDnmPim8Ehfj4NlHnlpdu8TFhMramqqqMJrYMfZ46 rPxYPKEb7CkuX/ExlnBZ5/KkmMQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:from:to:cc:subject:mime-version:content-type :content-transfer-encoding; s=default; bh=bIM3GMPjBzqJ4+zq04qo+l RkVwA=; b=ZKJ20BRlsAbF+HQ4VucW58Nqhlgtq6ia1fzM2dUn7zdQODsnvjQbgM mXCTraByHLyOG7oPDpZX4NLVALdqV7SDX/zfdEjhFR2RsbV48Szimf/Uv1HSZ+VD NiCV474Op/G/FzJFBoRZqQtZG3wMiCkshB3lKXktCtEp28oRMCbBU= Received: (qmail 47165 invoked by alias); 25 Jan 2020 14:14:06 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 47151 invoked by uid 89); 25 Jan 2020 14:14:06 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=delayslots, delay-slots, cook, carries X-HELO: smtp1.axis.com Received: from smtp1.axis.com (HELO smtp1.axis.com) (195.60.68.17) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 25 Jan 2020 14:14:04 +0000 IronPort-SDR: x8Oo8SYrGP1oEVVJL31E9uv1rOEICIFGf2JQ4jik4YH/Vr8g7kHjwurnM2csPNj0eFYA4jZBjq VSXx3HPeFLykikDlpxC3rRcEci44Q/vJzx5/Moea1wL1YIAd5heWWTG1WwSe8MIuSdb6QLsYAi 22gRIWxSAEkchy9SioLxeeejHSR8bkQGpTe3ljM3SA3KnOCIUzEPEzTQl8hiHIhPbdCBlvQ1Rz PjC+4FysW2ffCg+glIKA3SGFSmZmeXP58MGZsf3Q5mYM6FRP0lRpX51fr3cYIh+MjFjb47RATP VuA= Date: Sat, 25 Jan 2020 15:14:00 +0100 Message-ID: <202001251414.00PEE0CP020535@ignucius.se.axis.com> From: Hans-Peter Nilsson To: CC: Subject: [PATCH] dbr: Filter-out TARGET_FLAGS_REGNUM from end_of_function_needs. MIME-Version: 1.0 X-IsSubscribed: yes Compared to the cc0 version, I noticed a regression in delay-slot-filling for CRIS for several functions in libgcc with a similar layout, one being lshrdi3, where with cc0 all delay-slots were filled, as exposed by the test-case. I ended up including the thankfully-small lshrdi3 as-is, for simplicity of testing, after failing to cook up an artificial test-case. There's one slot that fails to be filled for the decc0rated CRIS port. A gdb session shows it is because of the automatic inclusion of TARGET_FLAGS_REGNUM in "registers needed at the end of the function" because there are insns in the epilogue that clobber the condition-code register. I'm not trying to tell a clobber from a set, as parallels with set instead of clobber seems likely to happen too, for targets with TARGET_FLAGS_REGNUM set. Other targets with delay-slots and one dedicated often-clobbered condition-code-register should consider defining TARGET_FLAGS_REGNUM. I noticed it improved delay-slot-filling also in other situations than this. (Author of introduction of TARGET_FLAGS_REGNUM use in dbr is CC:ed.) Tested cris-elf. Ok to commit or perhaps wait to gcc11? (The test-case goes in either way, as it passes with cc0-CRIS.) gcc: * resource.c (init_resource_info): Filter-out TARGET_FLAGS_REGNUM from end_of_function_needs. gcc/testsuite: * gcc.target/cris/pr93372-1.c: New. --- gcc/resource.c | 6 +++ gcc/testsuite/gcc.target/cris/pr93372-1.c | 62 +++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 gcc/testsuite/gcc.target/cris/pr93372-1.c diff --git a/gcc/resource.c b/gcc/resource.c index d26217c..62a69c0 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "backend.h" +#include "target.h" #include "rtl.h" #include "df.h" #include "memmodel.h" @@ -1214,6 +1215,11 @@ init_resource_info (rtx_insn *epilogue_insn) if (return_insn_p (epilogue_insn)) break; } + + /* Filter-out the flags register from those additionally required + registers. */ + if (targetm.flags_regnum != INVALID_REGNUM) + CLEAR_HARD_REG_BIT (end_of_function_needs.regs, targetm.flags_regnum); /* Allocate and initialize the tables used by mark_target_live_regs. */ target_hash_table = XCNEWVEC (struct target_info *, TARGET_HASH_PRIME); diff --git a/gcc/testsuite/gcc.target/cris/pr93372-1.c b/gcc/testsuite/gcc.target/cris/pr93372-1.c new file mode 100644 index 0000000..b625eda --- /dev/null +++ b/gcc/testsuite/gcc.target/cris/pr93372-1.c @@ -0,0 +1,62 @@ +/* Check that all more-or-less trivially fillable delayed-branch-slots + are filled. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "\tnop" } } */ + +void *f(void **p) +{ + /* Supposedly the memory read finds its way into the "ret" + delay-slot. */ + return *p; +} + +int g(int *x, int *y, char *v, int n) +{ + int z = *x; + int w = *v + 31; + + /* Two branch and two return slots, all filled. */ + if (z != 23 && z != n+1) + return *x+*y+24+w; + return *y+24+w; +} + +/* No problem with the two examples above, but with a more involved + example, the epilogue contents matter (the condition-code register + clobber was mistaken for a register that needed to be alive). */ + +struct DWstruct {int low, high;}; +typedef unsigned long long DItype; +typedef unsigned int USItype; + +typedef union +{ + struct DWstruct s; + DItype ll; +} DWunion; + +unsigned long long +xlshrdi3 (DItype u, unsigned int b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const int bm = (4 * 8) - b; + DWunion w; + + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (USItype) uu.s.high >> -bm; + } + else + { + const USItype carries = (USItype) uu.s.high << bm; + w.s.high = (USItype) uu.s.high >> b; + w.s.low = ((USItype) uu.s.low >> b) | carries; + } + + return w.ll; +}