]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Rewrite index*1+disp into base+disp
authorLIU Hao <lh_mouse@126.com>
Fri, 29 May 2026 10:17:53 +0000 (12:17 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Fri, 29 May 2026 11:09:44 +0000 (13:09 +0200)
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 <lh_mouse@126.com>
gcc/config/i386/i386.cc
gcc/testsuite/gcc.target/i386/rewrite-sib-without-base.c [new file with mode: 0644]

index dd1f715b460b7fc87fbe1eeb2348159e269a2efb..ac89829641619419297b6ea47a98ea7617b13104 100644 (file)
@@ -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 (file)
index 0000000..6eaa384
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-not "\\(,%" } } */
+
+_Complex a;
+_Complex int b;
+void c(void) { a = *(_Complex char *)__builtin_memset(&a, 1, 2) / b; }