https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82267

--- Comment #7 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Peter Cordes from comment #6)
> (In reply to H.J. Lu from comment #2)
> > > Are there still cases where -maddress-mode=long makes worse code?
> > 
> > 
> > Yes, there are more places where -maddress-mode=long needs to zero-extend
> > address to 64 bits where 0x67 prefix does for you.
> 
> So ideally, gcc should use 0x67 opportunistically where it saves a
> zero-extension instruction.

This is already implemented via:

;; Return true for RTX codes that force SImode address.
(define_predicate "SImode_address_operand"
  (match_code "subreg,zero_extend,and"))

and:

      /* Print SImode register names to force addr32 prefix.  */
      if (SImode_address_operand (addr, VOIDmode))
        {
          [...]
          gcc_assert (!code);
          code = 'k';
        }

in ix86_print_operand_address.

> Using 64-bit address size opportunistically wherever we're sure it's safe
> seems like a good idea, but I assume that's not easy to implement.
> 
> Can we teach  -maddress-mode=long  that a 0x67 prefix is a nearly-free way
> to zero-extend as part of an addressing-mode, so it will use that instead of
> extra instructions?

Please see above. It all boils down to combine being smart enough to combine
zero-extensions with the address. LEA also handles these kind of
zero-extensions.

> Note that %rsp can't be an index register, so you only have to check if it's
> the base register.

That is true, and this fact slipped out of my mind. I'm testing the following
patch:

Index: i386.c
===================================================================
--- i386.c      (revision 253208)
+++ i386.c      (working copy)
@@ -19953,12 +19953,11 @@
          code = 'k';
        }

-      /* Since the upper 32 bits of RSP are always zero for x32, we can
-        encode %esp as %rsp to avoid 0x67 prefix if there is no index or
-        base register.  */
+      /* Since the upper 32 bits of RSP are always zero for x32,
+        we can encode %esp as %rsp to avoid 0x67 prefix if
+        there is no index register.  */
       if (TARGET_X32 && Pmode == SImode
-         && ((!index && base && REG_P (base) && REGNO (base) == SP_REG)
-             || (!base && index && REGNO (index) == SP_REG)))
+         && !index && base && REG_P (base) && REGNO (base) == SP_REG)
        code = 'q';

       if (ASSEMBLER_DIALECT == ASM_ATT)

> 
> The SIB encodings that would mean index=RSP actually mean "no index".  The
> ModRM encoding that would mean base=RSP instead means "there's a SIB byte". 
> https://stackoverflow.com/a/46263495/224132
> 
> This means that `(%rsp)` is encodeable, instead of (%rsp, %rsp, scale).  Any
> other register can be used as a base with no SIB byte (unfortunately for
> code-size with -fomit-frame-pointer).
> 
> Can this check be applied to  %rbp  in functions that use a frame pointer?
> 
> That might be possible even if we can't as easily decide whether other
> registers need to be zero or sign extended if we're not sure whether they're
> "the pointer" or a signed integer pointer-difference.
> 
> However, simple dereference addressing modes (one register, no displacement)
> can always use 64-bit address size when the register is known to be
> zero-extended.

Reply via email to