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),%eax


I 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_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


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

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to