From: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
To: GCC Patches <gcc-patches@gcc.gnu.org>
Cc: Richard Sandiford <Richard.Sandiford@arm.com>,
Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>
Subject: [PATCH] AArch64: Improve immediate expansion [PR105928]
Date: Thu, 14 Sep 2023 15:24:38 +0000 [thread overview]
Message-ID: <PAWPR08MB8982EE0BF538316B9E8F9CCE83F7A@PAWPR08MB8982.eurprd08.prod.outlook.com> (raw)
Support immediate expansion of immediates which can be created from 2 MOVKs
and a shifted ORR or BIC instruction. Change aarch64_split_dimode_const_store
to apply if we save one instruction.
This reduces the number of 4-instruction immediates in SPECINT/FP by 5%.
Passes regress, OK for commit?
gcc/ChangeLog:
PR target/105928
* config/aarch64/aarch64.cc (aarch64_internal_mov_immediate)
Add support for immediates using shifted ORR/BIC.
(aarch64_split_dimode_const_store): Apply if we save one instruction.
* config/aarch64/aarch64.md (<LOGICAL:optab>_<SHIFT:optab><mode>3):
Make pattern global.
gcc/testsuite:
PR target/105928
* gcc.target/aarch64/pr105928.c: Add new test.
* gcc.target/aarch64/vect-cse-codegen.c: Fix test.
---
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index c44c0b979d0cc3755c61dcf566cfddedccebf1ea..832f8197ac8d1a04986791e6f3e51861e41944b2 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -5639,7 +5639,7 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
machine_mode mode)
{
int i;
- unsigned HOST_WIDE_INT val, val2, mask;
+ unsigned HOST_WIDE_INT val, val2, val3, mask;
int one_match, zero_match;
int num_insns;
@@ -5721,6 +5721,35 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
}
return 3;
}
+
+ /* Try shifting and inserting the bottom 32-bits into the top bits. */
+ val2 = val & 0xffffffff;
+ val3 = 0xffffffff;
+ val3 = val2 | (val3 << 32);
+ for (i = 17; i < 48; i++)
+ if ((val2 | (val2 << i)) == val)
+ {
+ if (generate)
+ {
+ emit_insn (gen_rtx_SET (dest, GEN_INT (val2 & 0xffff)));
+ emit_insn (gen_insv_immdi (dest, GEN_INT (16),
+ GEN_INT (val2 >> 16)));
+ emit_insn (gen_ior_ashldi3 (dest, dest, GEN_INT (i), dest));
+ }
+ return 3;
+ }
+ else if ((val3 & ~(val3 << i)) == val)
+ {
+ if (generate)
+ {
+ emit_insn (gen_rtx_SET (dest, GEN_INT (val3 | 0xffff0000)));
+ emit_insn (gen_insv_immdi (dest, GEN_INT (16),
+ GEN_INT (val2 >> 16)));
+ emit_insn (gen_and_one_cmpl_ashldi3 (dest, dest, GEN_INT (i),
+ dest));
+ }
+ return 3;
+ }
}
/* Generate 2-4 instructions, skipping 16 bits of all zeroes or ones which
@@ -25506,8 +25535,6 @@ aarch64_split_dimode_const_store (rtx dst, rtx src)
rtx lo = gen_lowpart (SImode, src);
rtx hi = gen_highpart_mode (SImode, DImode, src);
- bool size_p = optimize_function_for_size_p (cfun);
-
if (!rtx_equal_p (lo, hi))
return false;
@@ -25526,14 +25553,8 @@ aarch64_split_dimode_const_store (rtx dst, rtx src)
MOV w1, 49370
MOVK w1, 0x140, lsl 16
STP w1, w1, [x0]
- So we want to perform this only when we save two instructions
- or more. When optimizing for size, however, accept any code size
- savings we can. */
- if (size_p && orig_cost <= lo_cost)
- return false;
-
- if (!size_p
- && (orig_cost <= lo_cost + 1))
+ So we want to perform this when we save at least one instruction. */
+ if (orig_cost <= lo_cost)
return false;
rtx mem_lo = adjust_address (dst, SImode, 0);
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 97f70d39cc0ddeb330e044bae0544d85a695567d..932d4d47a5db1a74e0d0565b565afbd769090853 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4618,7 +4618,7 @@ (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
[(set_attr "type" "logics_shift_imm")]
)
-(define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
+(define_insn "<LOGICAL:optab>_<SHIFT:optab><mode>3"
[(set (match_operand:GPI 0 "register_operand" "=r")
(LOGICAL:GPI (SHIFT:GPI
(match_operand:GPI 1 "register_operand" "r")
diff --git a/gcc/testsuite/gcc.target/aarch64/pr105928.c b/gcc/testsuite/gcc.target/aarch64/pr105928.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab52247df66020d0b8fe70bc81f572e8b64c2bb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr105928.c
@@ -0,0 +1,43 @@
+/* { dg-do assemble } */
+/* { dg-options "-O2 --save-temps" } */
+
+long f1 (void)
+{
+ return 0x80402010080400;
+}
+
+long f2 (void)
+{
+ return 0x1234567812345678;
+}
+
+long f3 (void)
+{
+ return 0x4567800012345678;
+}
+
+long f4 (void)
+{
+ return 0x3ecccccd3ecccccd;
+}
+
+long f5 (void)
+{
+ return 0x38e38e38e38e38e;
+}
+
+long f6 (void)
+{
+ return 0x1745d1745d1745d;
+}
+
+void f7 (long *p)
+{
+ *p = 0x1234567812345678;
+}
+
+/* { dg-final { scan-assembler-times {\tmovk\t} 7 } } */
+/* { dg-final { scan-assembler-times {\tmov\t} 7 } } */
+/* { dg-final { scan-assembler-times {\tbic\t} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\t} 4 } } */
+/* { dg-final { scan-assembler-times {\tstp\t} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-cse-codegen.c b/gcc/testsuite/gcc.target/aarch64/vect-cse-codegen.c
index d025e989a1e67f00f4f4ce94897a961d38abfab7..2b8e64313bb47f995f071c728b1d84473807bc64 100644
--- a/gcc/testsuite/gcc.target/aarch64/vect-cse-codegen.c
+++ b/gcc/testsuite/gcc.target/aarch64/vect-cse-codegen.c
@@ -72,8 +72,7 @@ test3 (uint32_t a, uint32x4_t b, uint32x4_t* rt)
** ushr v[0-9]+.16b, v[0-9]+.16b, 7
** mov x[0-9]+, 16512
** movk x[0-9]+, 0x1020, lsl 16
-** movk x[0-9]+, 0x408, lsl 32
-** movk x[0-9]+, 0x102, lsl 48
+** orr x[0-9]+, x[0-9]+, x[0-9]+, lsl 28
** fmov d[0-9]+, x[0-9]+
** pmull v[0-9]+.1q, v[0-9]+.1d, v[0-9]+.1d
** dup v[0-9]+.2d, v[0-9]+.d\[0\]
next reply other threads:[~2023-09-14 15:24 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-14 15:24 Wilco Dijkstra [this message]
2023-09-17 11:04 ` Richard Sandiford
2023-09-18 17:41 ` Wilco Dijkstra
2023-09-19 8:49 ` Richard Sandiford
2023-09-19 12:57 ` Wilco Dijkstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=PAWPR08MB8982EE0BF538316B9E8F9CCE83F7A@PAWPR08MB8982.eurprd08.prod.outlook.com \
--to=wilco.dijkstra@arm.com \
--cc=Kyrylo.Tkachov@arm.com \
--cc=Richard.Sandiford@arm.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).