From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2059) id 532F03858D28; Thu, 26 Jan 2023 18:34:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 532F03858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1674758040; bh=gV6+TbZmWKXPJXj0uLHQp70xwDBb90U+x5yvMv2gvVY=; h=From:To:Subject:Date:From; b=Yvp/RfbPDJatDXB84lU6okoL8CZtVFFXuPpomFaHFb7mLtTtWVU9ajLNPJe4ZHrZ+ RRfnFyJOQnppjqUhNo3o19jarrORCpWwOcvtqP6xhuQ3NQpl9RoFVgU392KNiU3f2n viyDKavNSfGjrpYCGdHHgI3oh3fa3J05GABF61y8= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Dimitar Dimitrov To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-10488] pru: Fix CLZ expansion for QI and HI modes X-Act-Checkin: gcc X-Git-Author: Dimitar Dimitrov X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: 6b51b85313261e2864a530e61fd05f4ba7ccb444 X-Git-Newrev: 1486ade98c4344e1ce526f02a4d53fcf905d42ea Message-Id: <20230126183400.532F03858D28@sourceware.org> Date: Thu, 26 Jan 2023 18:34:00 +0000 (GMT) List-Id: https://gcc.gnu.org/g:1486ade98c4344e1ce526f02a4d53fcf905d42ea commit r11-10488-g1486ade98c4344e1ce526f02a4d53fcf905d42ea Author: Dimitar Dimitrov Date: Sat Jan 21 18:10:59 2023 +0200 pru: Fix CLZ expansion for QI and HI modes The recent gcc.dg/tree-ssa/clz-char.c test case failed for PRU target, exposing a wrong code generation bug in the PRU backend. The "clz" pattern did not produce correct output for QI and HI input operand modes. SI mode is ok. The "clz" pattern is expanded to an LMBD instruction to get the left-most bit position having value "1". In turn, to get the correct "clz" value, that bit position must be subtracted from the MSB bit position of the input operand. The old behaviour of hard-coding 31 for MSB bit position is wrong. The LMBD instruction returns 32 if input operand is zero, irrespective of its register mode. This maps nicely for SI mode, where the "clz" pattern outputs -1. It also leads to peculiar (but valid!) output values from the "clz" pattern for QI and HI zero-valued inputs. The corresponding commit in trunk contains two new test cases, which have been removed here because they depend on r13-5195-g4798080d4a3530. Regtested for pru-unknown-elf. gcc/ChangeLog: * config/pru/pru.h (CLZ_DEFINED_VALUE_AT_ZERO): Fix value for QI and HI input modes. * config/pru/pru.md (clz): Fix generated code for QI and HI input modes. Signed-off-by: Dimitar Dimitrov (cherry picked from commit c517295940a23db8ca165dfd5d0edea4457eda49) Diff: --- gcc/config/pru/pru.h | 5 +++-- gcc/config/pru/pru.md | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/gcc/config/pru/pru.h b/gcc/config/pru/pru.h index 4c35a7d7ee3..41260b9450d 100644 --- a/gcc/config/pru/pru.h +++ b/gcc/config/pru/pru.h @@ -562,8 +562,9 @@ do { \ #define CASE_VECTOR_MODE Pmode -/* See definition of clz pattern for rationale of value -1. */ -#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2) +/* See definition of clz pattern for rationale of the value. */ +#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ + ((VALUE) = GET_MODE_BITSIZE (MODE) - 1 - 32, 2) /* Jumps are cheap on PRU. */ #define LOGICAL_OP_NON_SHORT_CIRCUIT 0 diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md index e6cfa8ec3bf..c5661adb6c4 100644 --- a/gcc/config/pru/pru.md +++ b/gcc/config/pru/pru.md @@ -1035,8 +1035,16 @@ [(set_attr "type" "control")]) ;; Count Leading Zeros implemented using LMBD. -;; LMBD returns 32 if bit value is not present, and we subtract 31 to get CLZ. -;; Hence we get a defined value -1 for CLZ_DEFINED_VALUE_AT_ZERO. +;; +;; LMBD returns 32 if bit value is not present, for any kind of input MODE. +;; The LMBD's search result for a "1" bit is subtracted from the +;; mode bit size minus one, in order to get CLZ. +;; +;; Hence for SImode we get a defined value -1 for CLZ_DEFINED_VALUE_AT_ZERO. +;; +;; The QImode and HImode defined values for zero inputs end up to be +;; non-standard (-25 and -17). But this is considered acceptable in +;; order to keep the CLZ expansion to only two instructions. (define_expand "clz2" [(set (match_operand:QISI 0 "register_operand") (clz:QISI (match_operand:QISI 1 "register_operand")))] @@ -1047,7 +1055,8 @@ rtx tmpval = gen_reg_rtx (mode); emit_insn (gen_pru_lmbd (mode, tmpval, src, const1_rtx)); - emit_insn (gen_sub3_insn (dst, GEN_INT (31), tmpval)); + int msb_bitn = GET_MODE_BITSIZE (mode) - 1; + emit_insn (gen_sub3_insn (dst, GEN_INT (msb_bitn), tmpval)); DONE; })