Hello, Compiling the testcase in the attached patch with `gcc -O2` produces this instruction:
8d 04 05 01 00 00 00 lea 0x1(,%rax,1),%eax This patch rewrites it into the shorter equivalent: 8d 40 01 lea 0x1(%rax),%eaxI have bootstrapped GCC with C and C++ with this change on x86_64-linux-gnu, and ran gcc and g++ testsuites and there was no new failure. (I didn't run all tests, since it would take too much time; bootstrapping and running only gcc and g++ tests already took 6 hours for each iteration.)
I have also bootstrapped GCC on x86_64-w64-mingw32 and i686-w64-mingw32 and seen no new issues. I don't have write access to GCC repo, so please commit this change for me as you see fit. Thanks. From 12fb46bee5d5c2454e1e50e02d05e1cbbb90eb71 Mon Sep 17 00:00:00 2001 From: LIU Hao <[email protected]> Date: Thu, 28 May 2026 18:06:32 +0800 Subject: [PATCH] gcc/i386: Rewrite index*1+disp into base+disp Sometimes, GCC may synthesize an address like [index * 1 + displacement]. This commit rewrites that into [base + displacement], to eliminate the requirement of an SIB byte (which is always the case, as RSP isn't a valid index), and to allow a small displacement to be encoded in one byte. gcc/ChangeLog: * config/i386/i386.cc (ix86_decompose_address): Add a special case where there's no base, there's an index, and the scale is 1. gcc/testsuite/ChangeLog: * gcc.target/i386/rewrite-sib-without-base.c: New test. Signed-off-by: LIU Hao <[email protected]> --- gcc/config/i386/i386.cc | 4 ++++ gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index dd1f715b460b..ac8982964161 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -11504,6 +11504,10 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) std::swap (base_reg, index_reg); } + /* Special case: rewrite index*1+disp into base+disp. */ + if (!base && index && scale == 1) + base = index, base_reg = index_reg, index = index_reg = NULL_RTX; + /* Special case: %ebp cannot be encoded as a base without a displacement. Similarly %r13. */ if (!disp && base_regdiff --git a/gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c b/gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c
new file mode 100644
index 000000000000..574399e8b016
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "\\(,%" } } */
+
+_Complex a;
+_Complex int b;
+void c(void) { a = *(_Complex char *)__builtin_memset(&a, 1, 2) / b; }
--
2.54.0
From 12fb46bee5d5c2454e1e50e02d05e1cbbb90eb71 Mon Sep 17 00:00:00 2001 From: LIU Hao <[email protected]> Date: Thu, 28 May 2026 18:06:32 +0800 Subject: [PATCH] gcc/i386: Rewrite index*1+disp into base+disp Sometimes, GCC may synthesize an address like [index * 1 + displacement]. This commit rewrites that into [base + displacement], to eliminate the requirement of an SIB byte (which is always the case, as RSP isn't a valid index), and to allow a small displacement to be encoded in one byte. gcc/ChangeLog: * config/i386/i386.cc (ix86_decompose_address): Add a special case where there's no base, there's an index, and the scale is 1. gcc/testsuite/ChangeLog: * gcc.target/i386/rewrite-sib-without-base.c: New test. Signed-off-by: LIU Hao <[email protected]> --- gcc/config/i386/i386.cc | 4 ++++ gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index dd1f715b460b..ac8982964161 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -11504,6 +11504,10 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) std::swap (base_reg, index_reg); } + /* Special case: rewrite index*1+disp into base+disp. */ + if (!base && index && scale == 1) + base = index, base_reg = index_reg, index = index_reg = NULL_RTX; + /* Special case: %ebp cannot be encoded as a base without a displacement. Similarly %r13. */ if (!disp && base_reg diff --git a/gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c b/gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c new file mode 100644 index 000000000000..574399e8b016 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "\\(,%" } } */ + +_Complex a; +_Complex int b; +void c(void) { a = *(_Complex char *)__builtin_memset(&a, 1, 2) / b; } -- 2.54.0
OpenPGP_signature.asc
Description: OpenPGP digital signature
