public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 2/2] combine: Don't turn (mult (extend x) 2^n) into extract
@ 2020-10-15  8:59 Alex Coplan
  2020-10-22  8:36 ` Alex Coplan
                   ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: Alex Coplan @ 2020-10-15  8:59 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Sandiford, Segher Boessenkool

[-- Attachment #1: Type: text/plain, Size: 1930 bytes --]

Currently, make_extraction() identifies where we can emit an ASHIFT of
an extend in place of an extraction, but fails to make the corresponding
canonicalization/simplification when presented with a MULT by a power of
two. Such a representation is canonical when representing a left-shifted
address inside a MEM.

This patch remedies this situation: after the patch, make_extraction()
now also identifies RTXs such as:

(mult:DI (subreg:DI (reg:SI r)) (const_int 2^n))

and rewrites this as:

(mult:DI (sign_extend:DI (reg:SI r)) (const_int 2^n))

instead of using a sign_extract.

(This patch also fixes up a comment in expand_compound_operation() which
appears to have suffered from bitrot.)

This fixes several quality regressions on AArch64 after removing support for
addresses represented as sign_extract insns (1/2).

In particular, after the fix for PR96998, for the relevant testcase, we
have:

.L2:
        sxtw    x0, w0  // 8    [c=4 l=4]  *extendsidi2_aarch64/0
        add     x0, x19, x0, lsl 2      // 39   [c=8 l=4]  *add_lsl_di
        bl      h               // 11   [c=4 l=4]  *call_value_insn/1
        b       .L2             // 54   [c=4 l=4]  jump

and after this patch, we have:

.L2:
        add     x0, x19, w0, sxtw 2     // 39   [c=8 l=4]  *add_extendsi_shft_di
        bl      h               // 11   [c=4 l=4]  *call_value_insn/1
        b       .L2             // 54   [c=4 l=4]  jump

which restores the original optimal sequence we saw before the AArch64
patch.

Testing:
 * Bootstrapped and regtested on aarch64-linux-gnu, arm-linux-gnueabihf,
   and x86_64-linux-gnu.

OK for trunk?

Thanks,
Alex

---

gcc/ChangeLog:

	* combine.c (expand_compound_operation): Tweak variable name in
	comment to match source.
	(make_extraction): Handle mult by power of two in addition to
	ashift.

---
 gcc/combine.c | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

[-- Attachment #2: 0002-combine-Don-t-turn-mult-extend-x-2-n-into-extract.patch --]
[-- Type: text/x-patch, Size: 2421 bytes --]

diff --git a/gcc/combine.c b/gcc/combine.c
index 4782e1d9dcc..88f3925aee7 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7419,8 +7419,8 @@ expand_compound_operation (rtx x)
     }
 
   /* If we reach here, we want to return a pair of shifts.  The inner
-     shift is a left shift of BITSIZE - POS - LEN bits.  The outer
-     shift is a right shift of BITSIZE - LEN bits.  It is arithmetic or
+     shift is a left shift of MODEWIDTH - POS - LEN bits.  The outer
+     shift is a right shift of MODEWIDTH - LEN bits.  It is arithmetic or
      logical depending on the value of UNSIGNEDP.
 
      If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will be
@@ -7650,20 +7650,27 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
 	is_mode = GET_MODE (SUBREG_REG (inner));
       inner = SUBREG_REG (inner);
     }
-  else if (GET_CODE (inner) == ASHIFT
+  else if ((GET_CODE (inner) == ASHIFT || GET_CODE (inner) == MULT)
 	   && CONST_INT_P (XEXP (inner, 1))
-	   && pos_rtx == 0 && pos == 0
-	   && len > UINTVAL (XEXP (inner, 1)))
-    {
-      /* We're extracting the least significant bits of an rtx
-	 (ashift X (const_int C)), where LEN > C.  Extract the
-	 least significant (LEN - C) bits of X, giving an rtx
-	 whose mode is MODE, then shift it left C times.  */
-      new_rtx = make_extraction (mode, XEXP (inner, 0),
-			     0, 0, len - INTVAL (XEXP (inner, 1)),
-			     unsignedp, in_dest, in_compare);
-      if (new_rtx != 0)
-	return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1));
+	   && pos_rtx == 0 && pos == 0)
+    {
+      const HOST_WIDE_INT ci = INTVAL (XEXP (inner, 1));
+      const auto code = GET_CODE (inner);
+      const HOST_WIDE_INT shift_amt = (code == MULT) ? exact_log2 (ci) : ci;
+
+      if (shift_amt > 0 && len > (unsigned HOST_WIDE_INT)shift_amt)
+	{
+	  /* We're extracting the least significant bits of an rtx
+	     (ashift X (const_int C)) or (mult X (const_int (2^C))),
+	     where LEN > C.  Extract the least significant (LEN - C) bits
+	     of X, giving an rtx whose mode is MODE, then shift it left
+	     C times.  */
+	  new_rtx = make_extraction (mode, XEXP (inner, 0),
+				 0, 0, len - shift_amt,
+				 unsignedp, in_dest, in_compare);
+	  if (new_rtx)
+	    return gen_rtx_fmt_ee (code, mode, new_rtx, XEXP (inner, 1));
+	}
     }
   else if (GET_CODE (inner) == TRUNCATE
 	   /* If trying or potentionally trying to extract

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2020-10-28 20:28 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-15  8:59 [PATCH 2/2] combine: Don't turn (mult (extend x) 2^n) into extract Alex Coplan
2020-10-22  8:36 ` Alex Coplan
2020-10-22 20:29   ` Segher Boessenkool
2020-10-22 20:39 ` Segher Boessenkool
2020-10-26 10:09   ` Alex Coplan
2020-10-26 10:48     ` Segher Boessenkool
2020-10-26 11:06       ` Alex Coplan
2020-10-26 11:10         ` Alex Coplan
2020-10-26 11:51         ` Segher Boessenkool
2020-10-26 13:18           ` Alex Coplan
2020-10-26 17:48             ` Segher Boessenkool
2020-10-25 20:49 ` Segher Boessenkool
2020-10-26 12:12 ` Segher Boessenkool
2020-10-26 13:28   ` Alex Coplan
2020-10-26 17:43     ` Segher Boessenkool
2020-10-27 10:35       ` Alex Coplan
2020-10-27 11:49         ` Alex Coplan
2020-10-27 22:31         ` Segher Boessenkool
2020-10-28  9:09           ` Alex Coplan
2020-10-28 11:13             ` Alex Coplan
2020-10-28 20:27               ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).