x86: suppress LEA optimization in a specific 16-bit case

Message ID 05b35df1-c3c7-05f6-bc76-3661a39845f0@suse.com
State New
Headers show
Series
  • x86: suppress LEA optimization in a specific 16-bit case
Related show

Commit Message

Libor Bukata via Binutils June 9, 2021, 7:03 a.m.
In 16-bit mode a 16-bit address size LEA with a 16-bit displacement and
a 32-bit destination is shorter to encode than the corresponding MOV.
Commit fe134c656991 ("x86: optimize LEA")'s promise was to only do the
transformation when the encoding size wouldn't grow, i.e. it did go a
little too far. Restrict this specific case of the transformation to
-O2.

gas/
2021-06-XX  Jan Beulich  <jbeulich@suse.com>

	* config/tc-i386.c (optimize_encoding): Suppress LEA conversion
	when it would grow code size in 16-bit mode.
	* testsuite/gas/i386/lea16-optimize.d: Adjust expectations.
	* testsuite/gas/i386/lea16-optimize2.d: New.
	* testsuite/gas/i386/i386.exp: Run new test.
---
The choice to keep the optimization at -O2 is pretty arbitrary; I'd be
okay to suppress the adjustment unconditionally (at which point the new
test case would go away again).

Comments

Libor Bukata via Binutils June 9, 2021, 12:19 p.m. | #1
On Wed, Jun 9, 2021 at 12:03 AM Jan Beulich <jbeulich@suse.com> wrote:
>

> In 16-bit mode a 16-bit address size LEA with a 16-bit displacement and

> a 32-bit destination is shorter to encode than the corresponding MOV.

> Commit fe134c656991 ("x86: optimize LEA")'s promise was to only do the

> transformation when the encoding size wouldn't grow, i.e. it did go a

> little too far. Restrict this specific case of the transformation to

> -O2.

>

> gas/

> 2021-06-XX  Jan Beulich  <jbeulich@suse.com>

>

>         * config/tc-i386.c (optimize_encoding): Suppress LEA conversion

>         when it would grow code size in 16-bit mode.

>         * testsuite/gas/i386/lea16-optimize.d: Adjust expectations.

>         * testsuite/gas/i386/lea16-optimize2.d: New.

>         * testsuite/gas/i386/i386.exp: Run new test.

> ---

> The choice to keep the optimization at -O2 is pretty arbitrary; I'd be

> okay to suppress the adjustment unconditionally (at which point the new

> test case would go away again).

>


OK.

Thanks.

-- 
H.J.

Patch

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4140,6 +4140,13 @@  optimize_encoding (void)
 			   ? i.op[1].regs->reg_type.bitfield.dword
 			   : i.op[1].regs->reg_type.bitfield.word)))
 	    return;
+	  /* In 16-bit mode converting LEA with 16-bit addressing and a 32-bit
+	     destination is going to grow encoding size.  */
+	  else if (flag_code == CODE_16BIT
+		   && (optimize <= 1 || optimize_for_space)
+		   && !i.prefix[ADDR_PREFIX]
+		   && i.op[1].regs->reg_type.bitfield.dword)
+	    return;
 	  else
 	    {
 	      i.tm.base_opcode = 0xb8;
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -544,6 +544,7 @@  if [gas_32_check] then {
     run_list_test "optimize-7" "-I${srcdir}/$subdir -march=+noavx2 -al"
     run_dump_test "lea-optimize"
     run_dump_test "lea16-optimize"
+    run_dump_test "lea16-optimize2"
     run_dump_test "align-branch-1a"
     run_dump_test "align-branch-1b"
     run_dump_test "align-branch-1c"
--- a/gas/testsuite/gas/i386/lea16-optimize.d
+++ b/gas/testsuite/gas/i386/lea16-optimize.d
@@ -31,9 +31,9 @@  Disassembly of section .text:
 [ 	]*[0-9a-f]+:[ 	]+8b f6[ 	]+mov[ 	]+%si,%si
 [ 	]*[0-9a-f]+:[ 	]+66 8b c9[ 	]+mov[ 	]+%ecx,%ecx
 [ 	]*[0-9a-f]+:[ 	]+66 8b c1[ 	]+mov[ 	]+%ecx,%eax
-[ 	]*[0-9a-f]+:[ 	]+66 b8 01 00 00 00[ 	]+mov[ 	]+\$0x1,%eax
+[ 	]*[0-9a-f]+:[ 	]+66 8d 06 01 00[ 	]+lea[ 	]+0x1,%eax
 [ 	]*[0-9a-f]+:[ 	]+b8 02 00[ 	]+mov[ 	]+\$0x2,%ax
-[ 	]*[0-9a-f]+:[ 	]+66 b8 ff ff 00 00[ 	]+mov[ 	]+\$0xffff,%eax
+[ 	]*[0-9a-f]+:[ 	]+66 8d 06 ff ff[ 	]+lea[ 	]+-0x1,%eax
 [ 	]*[0-9a-f]+:[ 	]+b8 fe ff[ 	]+mov[ 	]+\$0xfffe,%ax
 [ 	]*[0-9a-f]+:[ 	]+66 b8 01 00 00 00[ 	]+mov[ 	]+\$0x1,%eax
 [ 	]*[0-9a-f]+:[ 	]+b8 02 00[ 	]+mov[ 	]+\$0x2,%ax
@@ -43,7 +43,7 @@  Disassembly of section .text:
 [ 	]*[0-9a-f]+:[ 	]+b8 00 00[ 	]+mov[ 	]+\$0x0,%ax
 [ 	]*[0-9a-f]+:[ 	]+66 b8 00 00 00 00[ 	]+mov[ 	]+\$0x0,%eax
 [ 	]*[0-9a-f]+:[ 	]+67 8d 05 00 00 00 00[ 	]+addr32 lea[ 	]+0x0,%ax
-[ 	]*[0-9a-f]+:[ 	]+66 b8 00 00 00 00[ 	]+mov[ 	]+\$0x0,%eax
+[ 	]*[0-9a-f]+:[ 	]+66 8d 06 00 00[ 	]+lea[ 	]+0x0,%eax
 [ 	]*[0-9a-f]+:[ 	]+b8 00 00[ 	]+mov[ 	]+\$0x0,%ax
 [ 	]*[0-9a-f]+:[ 	]+8d 47 ff[ 	]+lea[ 	]+-0x1\(%bx\),%ax
 [ 	]*[0-9a-f]+:[ 	]+8d 87 01 00[ 	]+lea[ 	]+0x1\(%bx\),%ax
--- /dev/null
+++ b/gas/testsuite/gas/i386/lea16-optimize2.d
@@ -0,0 +1,50 @@ 
+#as: -O2 -q -I${srcdir}/$subdir
+#objdump: -dw -Mi8086
+#name: i386 16-bit LEA optimizations at -O2
+#source: lea16.s
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <start>:
+[ 	]*[0-9a-f]+:[ 	]+67 66 8d 04 08[ 	]+lea[ 	]+\(%eax,%ecx(,1)?\),%eax
+[ 	]*[0-9a-f]+:[ 	]+67 66 8d 04 08[ 	]+lea[ 	]+\(%eax,%ecx(,1)?\),%eax
+[ 	]*[0-9a-f]+:[ 	]+67 66 8d 48 01[ 	]+lea[ 	]+0x1\(%eax\),%ecx
+[ 	]*[0-9a-f]+:[ 	]+67 66 8d 88 00 00 00 00[ 	]+lea[ 	]+0x0\(%eax\),%ecx
+[ 	]*[0-9a-f]+:[ 	]+67 66 8d 0c 25 00 00 00 00[ 	]+addr32 lea[ 	]+0x0,%ecx
+[ 	]*[0-9a-f]+:[ 	]+67 66 8d 04 00[ 	]+lea[ 	]+\(%eax,%eax(,1)?\),%eax
+[ 	]*[0-9a-f]+:[ 	]+67 66 8d 04 45 00 00 00 00[ 	]+lea[ 	]+0x0\(,%eax,2\),%eax
+[ 	]*[0-9a-f]+:[ 	]+67 66 8d 04 25 00 00 00 00[ 	]+addr32 lea[ 	]+0x0,%eax
+[ 	]*[0-9a-f]+:[ 	]+66 8d 00[ 	]+lea[ 	]+\(%bx,%si\),%eax
+[ 	]*[0-9a-f]+:[ 	]+66 8b c0[ 	]+mov[ 	]+%eax,%eax
+[ 	]*[0-9a-f]+:[ 	]+66 8b c8[ 	]+mov[ 	]+%eax,%ecx
+[ 	]*[0-9a-f]+:[ 	]+66 8b c8[ 	]+mov[ 	]+%eax,%ecx
+[ 	]*[0-9a-f]+:[ 	]+66 8b c8[ 	]+mov[ 	]+%eax,%ecx
+[ 	]*[0-9a-f]+:[ 	]+66 8d 04[ 	]+lea[ 	]+\(%si\),%eax
+[ 	]*[0-9a-f]+:[ 	]+66 8d 34[ 	]+lea[ 	]+\(%si\),%esi
+[ 	]*[0-9a-f]+:[ 	]+66 8d 04[ 	]+lea[ 	]+\(%si\),%eax
+[ 	]*[0-9a-f]+:[ 	]+8b c0[ 	]+mov[ 	]+%ax,%ax
+[ 	]*[0-9a-f]+:[ 	]+8b c8[ 	]+mov[ 	]+%ax,%cx
+[ 	]*[0-9a-f]+:[ 	]+8b c8[ 	]+mov[ 	]+%ax,%cx
+[ 	]*[0-9a-f]+:[ 	]+8b c6[ 	]+mov[ 	]+%si,%ax
+[ 	]*[0-9a-f]+:[ 	]+8b f6[ 	]+mov[ 	]+%si,%si
+[ 	]*[0-9a-f]+:[ 	]+66 8b c9[ 	]+mov[ 	]+%ecx,%ecx
+[ 	]*[0-9a-f]+:[ 	]+66 8b c1[ 	]+mov[ 	]+%ecx,%eax
+[ 	]*[0-9a-f]+:[ 	]+66 b8 01 00 00 00[ 	]+mov[ 	]+\$0x1,%eax
+[ 	]*[0-9a-f]+:[ 	]+b8 02 00[ 	]+mov[ 	]+\$0x2,%ax
+[ 	]*[0-9a-f]+:[ 	]+66 b8 ff ff 00 00[ 	]+mov[ 	]+\$0xffff,%eax
+[ 	]*[0-9a-f]+:[ 	]+b8 fe ff[ 	]+mov[ 	]+\$0xfffe,%ax
+[ 	]*[0-9a-f]+:[ 	]+66 b8 01 00 00 00[ 	]+mov[ 	]+\$0x1,%eax
+[ 	]*[0-9a-f]+:[ 	]+b8 02 00[ 	]+mov[ 	]+\$0x2,%ax
+[ 	]*[0-9a-f]+:[ 	]+66 b8 ff ff ff ff[ 	]+mov[ 	]+\$0xffffffff,%eax
+[ 	]*[0-9a-f]+:[ 	]+b8 fe ff[ 	]+mov[ 	]+\$0xfffe,%ax
+[ 	]*[0-9a-f]+:[ 	]+66 8d 06 00 00[ 	]+lea[ 	]+0x0,%eax
+[ 	]*[0-9a-f]+:[ 	]+b8 00 00[ 	]+mov[ 	]+\$0x0,%ax
+[ 	]*[0-9a-f]+:[ 	]+66 b8 00 00 00 00[ 	]+mov[ 	]+\$0x0,%eax
+[ 	]*[0-9a-f]+:[ 	]+67 8d 05 00 00 00 00[ 	]+addr32 lea[ 	]+0x0,%ax
+[ 	]*[0-9a-f]+:[ 	]+66 b8 00 00 00 00[ 	]+mov[ 	]+\$0x0,%eax
+[ 	]*[0-9a-f]+:[ 	]+b8 00 00[ 	]+mov[ 	]+\$0x0,%ax
+[ 	]*[0-9a-f]+:[ 	]+8d 47 ff[ 	]+lea[ 	]+-0x1\(%bx\),%ax
+[ 	]*[0-9a-f]+:[ 	]+8d 87 01 00[ 	]+lea[ 	]+0x1\(%bx\),%ax
+#pass