View Revisions: Issue #36551

Summary 0036551: [Patch] EAX -> EDX:EAX sign extension shortcuts, and MOVSX shortcuts for AX register
Revision 2020-01-11 00:22 by J. Gareth Moreton
Description Find attached a couple of patches that search for instruction combinations that sign-extend EAX to EDX:EAX and attempt to convert them into more optimal forms via the CWDE/cwtl, CDQ/cltd, CDQE/cltq and CQO/cqto opcodes.

mov-cdq.patch, all take place in OptPass2MOV:

- movl %eax,%edx; sarl $31,%edx -> cltd
- movq %rax,%rdx; sarq $63,%rdx -> cqto (x86_64 only)

- movl %edx,%eax; sarl $31,%edx -> movl %edx,%eax; cltd (-Os only due to cltd's dependency on %eax)
- movq %rdx,%rax; sarq $63,%rdx -> movq %rdx,%rax; cqto (x86_64 only; -Os only due to cqto's dependency on %rax)

---

A more complex one - either of the following combinations (these sequences sign-extend a 32-bit integer to a 64-bit integer, so are common around Int64-types under i386):

movl r/m,%edx; movl %edx,%eax; sarl $31,%edx
movl r/m,%eax; movl %eax,%edx; sarl $31,%edx
movl r/m,%edx; movl r/m,%eax; sarl $31,%edx
movl r/m,%eax; movl r/m,%edx; sarl $31,%edx

...become...

movl r/m,%eax <-- always %eax, even if it was %edx before
cltd

----

A very complex one, not performed on x86_64 (the first 4 instructions are the implemention of Abs() for LongInt on x86 platforms that don't have CMOV available... x86_64 always has CMOV available):

movl %eax,%edx
sarl $31,%eax
xorl %eax,%edx
subl %eax,%edx
(instruction that uses %edx)
(%eax and %edx deallocated)

...becomes...

cltd
xorl %edx,%eax <-- note the registers have swapped
subl %edx,%eax
(instruction that uses %eax) <-- %eax rather than %edx

----

movsx-cdq.patch, all take place in a new PostPeepholeOptMOVSX routine:

movswl %ax,%eax -> cwtl
movslq %eax,%rax -> cltq (x86_64 only)
Revision 2020-01-11 00:14 by J. Gareth Moreton
Description Find attached a couple of patches that search for instruction combinations that sign-extend EAX to EDX:EAX and attempt to convert them into more optimal forms via the CWDE/cwtl, CDQ/cltd, CDQE/cltq and CQO/cqto opcodes.

mov-cdq.patch, all take place in OptPass2MOV:

- movl %eax,%edx; sarl $31,%edx -> cltd
- movq %rax,%rdx; sarq $63,%rdx -> cqto (x86_64 only)

- movl %edx,%eax; sarl $31,%edx -> movl %edx,%eax; cltd (-Os only due to cltd's dependency on %eax)
- movq %rdx,%rax; sarq $63,%rdx -> movq %rdx,%rax; cqto (x86_64 only; -Os only due to cqto's dependency on %rax)

---

A more complex one - either of the following combinations (these sequences sign-extend a 32-bit integer to a 64-bit integer, so are common around Int64-types under i386):

movl r/m,%edx; movl %edx,%eax; sarl $31,%edx
movl r/m,%eax; movl %eax,%edx; sarl $31,%edx
movl r/m,%edx; movl r/m,%eax; sarl $31,%edx
movl r/m,%eax; movl r/m,%edx; sarl $31,%edx

...become...

movl r/m,%eax <-- always %eax, even if it was %edx before
cltd

----

A very complex one, not performed on x86_64 (the first 4 instructions are the implemention of Abs() for LongInt on x86 platforms that don't have CMOV available... x86_64 always has CMOV available):

movl %eax,%edx
sarl $31,%eax
xorl %eax,%edx
subl %eax,%edx
(instruction that uses %edx)
(%eax and %edx deallocated)

...becomes...

cltd
xorl %edx,%eax <-- note the registers have swapped
subl %edx,%eax
(instruction that uses %eax) <-- %eax rather than %edx

----

movsdx-cdq.patch, all take place in a new PostPeepholeOptMOVSX routine:

movswl %ax,%eax -> cwtl
movslq %eax,%rax -> cltq (x86_64 only)
Revision 2020-01-11 00:11 by J. Gareth Moreton
Description Find attached a couple of patches that search for instruction combinations that sign-extend EAX to EDX:EAX and attempt to convert them into more optimal forms via the CWDE/cwtl, CDQ/cltd, CDQE/cltq and CQO/cqto opcodes.

mov-cdq.patch, all take place in OptPass2MOV:

- movl %eax,%edx; sarl $31,%edx -> cltd
- movq %rax,%rdx; sarq $63,%rdx -> cqto (x86_64 only)

- movl %edx,%eax; sarl $31,%edx -> movl %edx,%eax; cltd (-Os only due to cltd's dependency on %eax)
- movq %rdx,%rax; sarq $63,%rdx -> movq %rdx,%rax; cqto (x86_64 only; -Os only due to cqto's dependency on %rax)

---

A more complex one - either of the following combinations (these sequences sign-extend a 32-bit integer to a 64-bit integer, so are common around Int64-types under i386):

movl r/m,%edx; movl %edx,%eax; sarl $31,%edx
movl r/m,%eax; movl %eax,%edx; sarl $31,%edx
movl r/m,%edx; movl r/m,%eax; sarl $31,%edx
movl r/m,%eax; movl r/m,%edx; sarl $31,%edx

...become...

movl r/m,%eax <-- always %eax, even if it was %edx before
cltd

----

A very complex one, not performed on x86_64 (the first 4 instructions are the implemention of Abs() for LongInt on x86 platforms that don't have CMOV available... x86_64 always has CMOV available):

movl %eax,%edx
sarl $31,%eax
xorl %eax,%edx
subl %eax,%edx
(instruction that uses %edx)
(%eax and %edx deallocated)

...becomes...

cltd
xorl %edx,%eax <-- note the registers have swapped
subl %edx,%eax
(instruction that uses %eax) <-- %eax rather than %edx

----

movsdx-cdq.patch, all take place in a new PostPeepholeOptMOVSX routine:

movswl %ax,%edx -> cwtl
movslq %eax,%rdx -> cltq (x86_64 only)
Revision 2020-01-11 00:07 by J. Gareth Moreton
Description Find attached a couple of patches that search for instruction combinations that sign-extend EAX to EDX:EAX and attempt to convert them into more optimal forms via the CWDE/cwtl, CDQ/cltd, CDQE/cltq and CQO/cqto opcodes.

mov-cdq.patch, all take place in OptPass2MOV:

- movl %eax,%edx; sarl $31,%edx -> cltd
- movq %rax,%rdx; sarq $63,%rdx -> cqto (x86_64 only)

- movl %edx,%eax; sarl $31,%edx -> movl %edx,%eax; cltd (-Os only due to cltd's dependency on %eax)
- movq %rdx,%rax; sarq $63,%rdx -> movq %rdx,%rax; cqto (x86_64 only; -Os only due to cltd's dependency on %rax)

---

A more complex one - either of the following combinations (these sequences sign-extend a 32-bit integer to a 64-bit integer):

movl r/m,%edx; movl %edx,%eax; sarl $31,%edx
movl r/m,%eax; movl %eax,%edx; sarl $31,%edx
movl r/m,%edx; movl r/m,%eax; sarl $31,%edx
movl r/m,%eax; movl r/m,%edx; sarl $31,%edx

...become...

movl r/m,%eax <-- always %eax, even if it was %edx before
cltd

----

A very complex one, not performed on x86_64 (the first 4 instructions are the implemention of Abs() for LongInt on x86 platforms that don't have CMOV available):

movl %eax,%edx
sarl $31,%eax
xorl %eax,%edx
subl %eax,%edx
(instruction that uses %edx)
(%eax and %edx deallocated)

...becomes...

cltd
xorl %edx,%eax <-- note the registers have swapped
subl %edx,%eax
(instruction that uses %eax) <-- %eax rather than %edx

----

movsdx-cdq.patch, all take place in a new PostPeepholeOptMOVSX routine:

movswl %ax,%edx -> cwtl
movslq %eax,%rdx -> cltq (x86_64 only)