[llvm] 7615da1 - [M68k] Finish implementation of `MOVX` (move and extend) pseudo-instructions and fix related errors (#218938)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 26 15:41:02 PDT 2026


Author: Dan Salvato
Date: 2026-09-26T17:40:51-05:00
New Revision: 7615da10b75c57286a4032eac8bb43c1b8d2ba46

URL: https://github.com/llvm/llvm-project/commit/7615da10b75c57286a4032eac8bb43c1b8d2ba46
DIFF: https://github.com/llvm/llvm-project/commit/7615da10b75c57286a4032eac8bb43c1b8d2ba46.diff

LOG: [M68k] Finish implementation of `MOVX` (move and extend) pseudo-instructions and fix related errors (#218938)

This patch adds remaining addressing modes to the "move and extend"
pseudo-instructions, and fixes a few errors and inconsistencies in the
logic that caused inefficient code generation.

- Remaining addressing modes were implemented to match non-pseudo `MOVE`
instructions.
- Names of the pseudos now correctly reflect the register classes they
operate on, e.g. `MOVZXd32r16` for XR16 -> DR32.
- Fixed an issue where `MOVZX` could be allocated to an address
register, which has no way to zero-extend the result. (There were even
some of these in the test `register-spills.ll`, emitted as illegal
instructions, but the test doesn't have instruction verification
enabled, so it wasn't caught.)
- Fixed some `extload` patterns where the register was unnecessarily
extended to 32 bits before being truncated to its final size, causing
redundant instructions to be omitted.
- Fixed `anyext` patterns lowering to `MOVZX` instead of `MOVX`, causing
unnecessary zero-extensions.
- An inconsistency was fixed where the expansion logic would perform a
source-sized move when loading from memory, but a destination-sized move
when moving between registers. They now always perform a source-sized
move, which improves clarity in the assembly output and has more
opportunity for future optimizations.

Added: 
    

Modified: 
    llvm/lib/Target/M68k/M68kExpandPseudo.cpp
    llvm/lib/Target/M68k/M68kInstrArithmetic.td
    llvm/lib/Target/M68k/M68kInstrData.td
    llvm/lib/Target/M68k/M68kInstrInfo.cpp
    llvm/lib/Target/M68k/M68kInstrInfo.h
    llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll
    llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
    llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
    llvm/test/CodeGen/M68k/Bits/btst.ll
    llvm/test/CodeGen/M68k/Control/cmp.ll
    llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
    llvm/test/CodeGen/M68k/Control/setcc.ll
    llvm/test/CodeGen/M68k/Data/load-extend.ll
    llvm/test/CodeGen/M68k/Data/sext-i1.ll
    llvm/test/CodeGen/M68k/register-spills.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
index 39e6eeb912a6e..39e2e5c5aa919 100644
--- a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
+++ b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
@@ -86,106 +86,179 @@ bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
   case M68k::MOVI32ri:
     return TII->ExpandMOVI(MIB, MVT::i32);
 
-  case M68k::MOVXd16d8:
-    return TII->ExpandMOVX_RR(MIB, MVT::i16, MVT::i8);
-  case M68k::MOVXd32d8:
-    return TII->ExpandMOVX_RR(MIB, MVT::i32, MVT::i8);
-  case M68k::MOVXd32d16:
-    return TII->ExpandMOVX_RR(MIB, MVT::i32, MVT::i16);
-
   case M68k::MOVSXd16d8:
     return TII->ExpandMOVSZX_RR(MIB, true, MVT::i16, MVT::i8);
   case M68k::MOVSXd32d8:
     return TII->ExpandMOVSZX_RR(MIB, true, MVT::i32, MVT::i8);
-  case M68k::MOVSXd32d16:
+  case M68k::MOVSXr32r16:
     return TII->ExpandMOVSZX_RR(MIB, true, MVT::i32, MVT::i16);
 
   case M68k::MOVZXd16d8:
     return TII->ExpandMOVSZX_RR(MIB, false, MVT::i16, MVT::i8);
   case M68k::MOVZXd32d8:
     return TII->ExpandMOVSZX_RR(MIB, false, MVT::i32, MVT::i8);
-  case M68k::MOVZXd32d16:
+  case M68k::MOVZXd32r16:
     return TII->ExpandMOVSZX_RR(MIB, false, MVT::i32, MVT::i16);
 
-  case M68k::MOVSXd16j8:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dj), MVT::i16,
-                                MVT::i8);
-  case M68k::MOVSXd32j8:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dj), MVT::i32,
-                                MVT::i8);
-  case M68k::MOVSXd32j16:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV16rj), MVT::i32,
-                                MVT::i16);
-
-  case M68k::MOVZXd16j8:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dj), MVT::i16,
-                                MVT::i8);
-  case M68k::MOVZXd32j8:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dj), MVT::i32,
-                                MVT::i8);
-  case M68k::MOVZXd32j16:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16rj), MVT::i32,
-                                MVT::i16);
-
-  case M68k::MOVSXd16p8:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dp), MVT::i16,
-                                MVT::i8);
-  case M68k::MOVSXd32p8:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dp), MVT::i32,
-                                MVT::i8);
-  case M68k::MOVSXd32p16:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV16rp), MVT::i32,
-                                MVT::i16);
-
-  case M68k::MOVZXd16p8:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dp), MVT::i16,
-                                MVT::i8);
-  case M68k::MOVZXd32p8:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dp), MVT::i32,
-                                MVT::i8);
-  case M68k::MOVZXd32p16:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16rp), MVT::i32,
-                                MVT::i16);
-
-  case M68k::MOVSXd16f8:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8df), MVT::i16,
-                                MVT::i8);
-  case M68k::MOVSXd32f8:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8df), MVT::i32,
-                                MVT::i8);
-  case M68k::MOVSXd32f16:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV16rf), MVT::i32,
-                                MVT::i16);
-
-  case M68k::MOVZXd16f8:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8df), MVT::i16,
-                                MVT::i8);
-  case M68k::MOVZXd32f8:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8df), MVT::i32,
-                                MVT::i8);
-  case M68k::MOVZXd32f16:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16rf), MVT::i32,
-                                MVT::i16);
+  case M68k::MOVXd16d8:
+    return TII->ExpandMOVX_RR(MIB, MVT::i16, MVT::i8);
+  case M68k::MOVXd32d8:
+    return TII->ExpandMOVX_RR(MIB, MVT::i32, MVT::i8);
+  case M68k::MOVXr32r16:
+    return TII->ExpandMOVX_RR(MIB, MVT::i32, MVT::i16);
 
+  case M68k::MOVSXd16o8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8do, MVT::i16, MVT::i8);
+  case M68k::MOVSXd16e8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8de, MVT::i16, MVT::i8);
+  case M68k::MOVSXd16k8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8dk, MVT::i16, MVT::i8);
   case M68k::MOVSXd16q8:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dq), MVT::i16,
-                                MVT::i8);
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8dq, MVT::i16, MVT::i8);
+  case M68k::MOVSXd16f8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8df, MVT::i16, MVT::i8);
+  case M68k::MOVSXd16p8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8dp, MVT::i16, MVT::i8);
+  case M68k::MOVSXd16b8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8db, MVT::i16, MVT::i8);
+  case M68k::MOVSXd16j8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8dj, MVT::i16, MVT::i8);
+
+  case M68k::MOVSXd32o8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8do, MVT::i32, MVT::i8);
+  case M68k::MOVSXd32e8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8de, MVT::i32, MVT::i8);
+  case M68k::MOVSXd32k8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8dk, MVT::i32, MVT::i8);
   case M68k::MOVSXd32q8:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dq), MVT::i32,
-                                MVT::i8);
-  case M68k::MOVSXd32q16:
-    return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV16dq), MVT::i32,
-                                MVT::i16);
-
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8dq, MVT::i32, MVT::i8);
+  case M68k::MOVSXd32f8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8df, MVT::i32, MVT::i8);
+  case M68k::MOVSXd32p8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8dp, MVT::i32, MVT::i8);
+  case M68k::MOVSXd32b8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8db, MVT::i32, MVT::i8);
+  case M68k::MOVSXd32j8:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV8dj, MVT::i32, MVT::i8);
+
+  case M68k::MOVSXr32o16:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV16ro, MVT::i32, MVT::i16);
+  case M68k::MOVSXr32e16:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV16re, MVT::i32, MVT::i16);
+  case M68k::MOVSXr32k16:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV16rk, MVT::i32, MVT::i16);
+  case M68k::MOVSXr32q16:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV16rq, MVT::i32, MVT::i16);
+  case M68k::MOVSXr32f16:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV16rf, MVT::i32, MVT::i16);
+  case M68k::MOVSXr32p16:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV16rp, MVT::i32, MVT::i16);
+  case M68k::MOVSXr32b16:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV16rb, MVT::i32, MVT::i16);
+  case M68k::MOVSXr32j16:
+    return TII->ExpandMOVSZX_RM(MIB, true, M68k::MOV16rj, MVT::i32, MVT::i16);
+
+  case M68k::MOVZXd16o8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8do, MVT::i16, MVT::i8);
+  case M68k::MOVZXd16e8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8de, MVT::i16, MVT::i8);
+  case M68k::MOVZXd16k8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8dk, MVT::i16, MVT::i8);
   case M68k::MOVZXd16q8:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dq), MVT::i16,
-                                MVT::i8);
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8dq, MVT::i16, MVT::i8);
+  case M68k::MOVZXd16f8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8df, MVT::i16, MVT::i8);
+  case M68k::MOVZXd16p8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8dp, MVT::i16, MVT::i8);
+  case M68k::MOVZXd16b8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8db, MVT::i16, MVT::i8);
+  case M68k::MOVZXd16j8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8dj, MVT::i16, MVT::i8);
+
+  case M68k::MOVZXd32o8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8do, MVT::i32, MVT::i8);
+  case M68k::MOVZXd32e8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8de, MVT::i32, MVT::i8);
+  case M68k::MOVZXd32k8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8dk, MVT::i32, MVT::i8);
   case M68k::MOVZXd32q8:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dq), MVT::i32,
-                                MVT::i8);
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8dq, MVT::i32, MVT::i8);
+  case M68k::MOVZXd32f8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8df, MVT::i32, MVT::i8);
+  case M68k::MOVZXd32p8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8dp, MVT::i32, MVT::i8);
+  case M68k::MOVZXd32b8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8db, MVT::i32, MVT::i8);
+  case M68k::MOVZXd32j8:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV8dj, MVT::i32, MVT::i8);
+
+  case M68k::MOVZXd32o16:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV16ro, MVT::i32, MVT::i16);
+  case M68k::MOVZXd32e16:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV16re, MVT::i32, MVT::i16);
+  case M68k::MOVZXd32k16:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV16rk, MVT::i32, MVT::i16);
   case M68k::MOVZXd32q16:
-    return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16dq), MVT::i32,
-                                MVT::i16);
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV16rq, MVT::i32, MVT::i16);
+  case M68k::MOVZXd32f16:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV16rf, MVT::i32, MVT::i16);
+  case M68k::MOVZXd32p16:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV16rp, MVT::i32, MVT::i16);
+  case M68k::MOVZXd32b16:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV16rb, MVT::i32, MVT::i16);
+  case M68k::MOVZXd32j16:
+    return TII->ExpandMOVSZX_RM(MIB, false, M68k::MOV16rj, MVT::i32, MVT::i16);
+
+  case M68k::MOVXd16o8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8do, MVT::i16, MVT::i8);
+  case M68k::MOVXd16e8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8de, MVT::i16, MVT::i8);
+  case M68k::MOVXd16k8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8dk, MVT::i16, MVT::i8);
+  case M68k::MOVXd16q8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8dq, MVT::i16, MVT::i8);
+  case M68k::MOVXd16f8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8df, MVT::i16, MVT::i8);
+  case M68k::MOVXd16p8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8dp, MVT::i16, MVT::i8);
+  case M68k::MOVXd16b8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8db, MVT::i16, MVT::i8);
+  case M68k::MOVXd16j8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8dj, MVT::i16, MVT::i8);
+
+  case M68k::MOVXd32o8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8do, MVT::i32, MVT::i8);
+  case M68k::MOVXd32e8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8de, MVT::i32, MVT::i8);
+  case M68k::MOVXd32k8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8dk, MVT::i32, MVT::i8);
+  case M68k::MOVXd32q8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8dq, MVT::i32, MVT::i8);
+  case M68k::MOVXd32f8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8df, MVT::i32, MVT::i8);
+  case M68k::MOVXd32p8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8dp, MVT::i32, MVT::i8);
+  case M68k::MOVXd32b8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8db, MVT::i32, MVT::i8);
+  case M68k::MOVXd32j8:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV8dj, MVT::i32, MVT::i8);
+
+  case M68k::MOVXr32o16:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV16ro, MVT::i32, MVT::i16);
+  case M68k::MOVXr32e16:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV16re, MVT::i32, MVT::i16);
+  case M68k::MOVXr32k16:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV16rk, MVT::i32, MVT::i16);
+  case M68k::MOVXr32q16:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV16rq, MVT::i32, MVT::i16);
+  case M68k::MOVXr32f16:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV16rf, MVT::i32, MVT::i16);
+  case M68k::MOVXr32p16:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV16rp, MVT::i32, MVT::i16);
+  case M68k::MOVXr32b16:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV16rb, MVT::i32, MVT::i16);
+  case M68k::MOVXr32j16:
+    return TII->ExpandMOVX_RM(MIB, M68k::MOV16rj, MVT::i32, MVT::i16);
 
   case M68k::MOVM8jm_P:
   case M68k::MOVM16jm_P:

diff  --git a/llvm/lib/Target/M68k/M68kInstrArithmetic.td b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
index e448cd5b031b3..b9e92dde3d0ad 100644
--- a/llvm/lib/Target/M68k/M68kInstrArithmetic.td
+++ b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
@@ -561,7 +561,7 @@ def EXT32 : MxExt<MxType32d, MxType16d>;
 def : Pat<(sext_inreg i16:$src, i8),  (EXT16 $src)>;
 def : Pat<(sext_inreg i32:$src, i16), (EXT32 $src)>;
 def : Pat<(sext_inreg i32:$src, i8),
-          (EXT32 (MOVXd32d16 (EXT16 (EXTRACT_SUBREG $src, MxSubRegIndex16Lo))))>;
+          (EXT32 (MOVXr32r16 (EXT16 (EXTRACT_SUBREG $src, MxSubRegIndex16Lo))))>;
 
 
 //===----------------------------------------------------------------------===//
@@ -669,22 +669,22 @@ def : Pat<(urem i8:$dst, i8:$opd),
 // RR i16
 def : Pat<(sdiv i16:$dst, i16:$opd),
           (EXTRACT_SUBREG
-            (SDIVd32d16 (MOVSXd32d16 $dst), $opd),
+            (SDIVd32d16 (MOVSXr32r16 $dst), $opd),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(udiv i16:$dst, i16:$opd),
           (EXTRACT_SUBREG
-            (UDIVd32d16 (MOVZXd32d16 $dst), $opd),
+            (UDIVd32d16 (MOVZXd32r16 $dst), $opd),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(srem i16:$dst, i16:$opd),
           (EXTRACT_SUBREG
-            (SWAP (SDIVd32d16 (MOVSXd32d16 $dst), $opd)),
+            (SWAP (SDIVd32d16 (MOVSXr32r16 $dst), $opd)),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(urem i16:$dst, i16:$opd),
           (EXTRACT_SUBREG
-            (SWAP (UDIVd32d16 (MOVZXd32d16 $dst), $opd)),
+            (SWAP (UDIVd32d16 (MOVZXd32r16 $dst), $opd)),
              MxSubRegIndex16Lo)>;
 
 // RI i8
@@ -711,22 +711,22 @@ def : Pat<(urem i8:$dst, Mxi8immSExt8:$opd),
 // RI i16
 def : Pat<(sdiv i16:$dst, Mxi16immSExt16:$opd),
           (EXTRACT_SUBREG
-            (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd),
+            (SDIVd32i16 (MOVSXr32r16 $dst), imm:$opd),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(udiv i16:$dst, Mxi16immSExt16:$opd),
           (EXTRACT_SUBREG
-            (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd),
+            (UDIVd32i16 (MOVZXd32r16 $dst), imm:$opd),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(srem i16:$dst, Mxi16immSExt16:$opd),
           (EXTRACT_SUBREG
-            (SWAP (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd)),
+            (SWAP (SDIVd32i16 (MOVSXr32r16 $dst), imm:$opd)),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(urem i16:$dst, Mxi16immSExt16:$opd),
           (EXTRACT_SUBREG
-            (SWAP (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd)),
+            (SWAP (UDIVd32i16 (MOVZXd32r16 $dst), imm:$opd)),
              MxSubRegIndex16Lo)>;
 
 
@@ -738,17 +738,17 @@ def UMULd32d32 : MxDiMuOp_DD_Long<"mulu.l", MxUMul, 0x130, /*SIGNED*/false>;
 // RR
 def : Pat<(mul i16:$dst, i16:$opd),
           (EXTRACT_SUBREG
-            (SMULd32d16 (MOVXd32d16 $dst), $opd),
+            (SMULd32d16 (MOVXr32r16 $dst), $opd),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(mulhs i16:$dst, i16:$opd),
           (EXTRACT_SUBREG
-            (SWAP (SMULd32d16 (MOVXd32d16 $dst), $opd)),
+            (SWAP (SMULd32d16 (MOVXr32r16 $dst), $opd)),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(mulhu i16:$dst, i16:$opd),
           (EXTRACT_SUBREG
-            (SWAP (UMULd32d16 (MOVXd32d16 $dst), $opd)),
+            (SWAP (UMULd32d16 (MOVXr32r16 $dst), $opd)),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(mul i32:$dst, i32:$opd), (SMULd32d32 $dst, $opd)>;
@@ -757,17 +757,17 @@ def : Pat<(mul i32:$dst, i32:$opd), (SMULd32d32 $dst, $opd)>;
 // RI
 def : Pat<(mul i16:$dst, Mxi16immSExt16:$opd),
           (EXTRACT_SUBREG
-            (SMULd32i16 (MOVXd32d16 $dst), imm:$opd),
+            (SMULd32i16 (MOVXr32r16 $dst), imm:$opd),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(mulhs i16:$dst, Mxi16immSExt16:$opd),
           (EXTRACT_SUBREG
-            (SWAP (SMULd32i16 (MOVXd32d16 $dst), imm:$opd)),
+            (SWAP (SMULd32i16 (MOVXr32r16 $dst), imm:$opd)),
              MxSubRegIndex16Lo)>;
 
 def : Pat<(mulhu i16:$dst, Mxi16immSExt16:$opd),
           (EXTRACT_SUBREG
-            (SWAP (UMULd32i16 (MOVXd32d16 $dst), imm:$opd)),
+            (SWAP (UMULd32i16 (MOVXr32r16 $dst), imm:$opd)),
              MxSubRegIndex16Lo)>;
 
 

diff  --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td
index 5a294e1fb3cda..7bf30e05d5d95 100644
--- a/llvm/lib/Target/M68k/M68kInstrData.td
+++ b/llvm/lib/Target/M68k/M68kInstrData.td
@@ -625,130 +625,85 @@ def MOVI32ri : MxPseudoMove_DI<MxType32r>;
 /// what registers are allocated for the operands and if they overlap we just
 /// extend the value if the registers are completely 
diff erent we need to move
 /// first.
-foreach EXT = ["S", "Z"] in {
-  let hasSideEffects = 0 in {
-
-    def MOV#EXT#Xd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
-    def MOV#EXT#Xd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
-    def MOV#EXT#Xd32d16 : MxPseudoMove_RR<MxType32r, MxType16r>;
-
+/// The MOVX group is similar to the others but does NOT do any value extension,
+/// they just load a smaller register into the lower part of another register
+/// if operands' real registers are 
diff erent or does nothing if they are the
+/// same.
+let hasSideEffects = 0 in {
+  foreach AM = MxMoveSrcAMs in {
+    defvar OpB8 = !cast<MxOpBundle>("MxOp8AddrMode_"#AM);
+    defvar OpB16 = !cast<MxOpBundle>("MxOp16AddrMode_"#AM);
     let mayLoad = 1 in {
-
-      def MOV#EXT#Xd16j8   : MxPseudoMove_RM<MxType16d,  MxType8.JOp>;
-      def MOV#EXT#Xd32j8   : MxPseudoMove_RM<MxType32d,  MxType8.JOp>;
-      def MOV#EXT#Xd32j16  : MxPseudoMove_RM<MxType32d, MxType16.JOp>;
-
-      def MOV#EXT#Xd16p8   : MxPseudoMove_RM<MxType16d,  MxType8.POp>;
-      def MOV#EXT#Xd32p8   : MxPseudoMove_RM<MxType32d,  MxType8.POp>;
-      def MOV#EXT#Xd32p16  : MxPseudoMove_RM<MxType32d, MxType16.POp>;
-
-      def MOV#EXT#Xd16f8   : MxPseudoMove_RM<MxType16d,  MxType8.FOp>;
-      def MOV#EXT#Xd32f8   : MxPseudoMove_RM<MxType32d,  MxType8.FOp>;
-      def MOV#EXT#Xd32f16  : MxPseudoMove_RM<MxType32d, MxType16.FOp>;
-
-      def MOV#EXT#Xd16q8   : MxPseudoMove_RM<MxType16d,  MxType8.QOp>;
-      def MOV#EXT#Xd32q8   : MxPseudoMove_RM<MxType32d,  MxType8.QOp>;
-      def MOV#EXT#Xd32q16  : MxPseudoMove_RM<MxType32d,  MxType16.QOp>;
-
+      def MOVSXd16#AM#8 : MxPseudoMove_RM<MxType16d, OpB8.Op>;
+      def MOVSXd32#AM#8 : MxPseudoMove_RM<MxType32d, OpB8.Op>;
+      def MOVSXr32#AM#16 : MxPseudoMove_RM<MxType32r, OpB16.Op>;
+      def MOVZXd16#AM#8 : MxPseudoMove_RM<MxType16d, OpB8.Op>;
+      def MOVZXd32#AM#8 : MxPseudoMove_RM<MxType32d, OpB8.Op>;
+      def MOVZXd32#AM#16 : MxPseudoMove_RM<MxType32d, OpB16.Op>;
+      def MOVXd16#AM#8 : MxPseudoMove_RM<MxType16d, OpB8.Op>;
+      def MOVXd32#AM#8 : MxPseudoMove_RM<MxType32d, OpB8.Op>;
+      def MOVXr32#AM#16 : MxPseudoMove_RM<MxType32r, OpB16.Op>;
     }
   }
-}
 
-/// This group of instructions is similar to the group above but DOES NOT do
-/// any value extension, they just load a smaller register into the lower part
-/// of another register if operands' real registers are 
diff erent or does
-/// nothing if they are the same.
-def MOVXd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
-def MOVXd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
-def MOVXd32d16 : MxPseudoMove_RR<MxType32r, MxType16r>;
+  def MOVSXd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
+  def MOVSXd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
+  def MOVSXr32r16 : MxPseudoMove_RR<MxType32r, MxType16r>;
+  def MOVZXd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
+  def MOVZXd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
+  def MOVZXd32r16 : MxPseudoMove_RR<MxType32d, MxType16r>;
+  // TODO: MOVX d8 -> r16/32 is possible, but it causes regalloc to make bad
+  // decisions in handling 8-bit register spills. Test in register-spills.ll
+  // for future experimentation.
+  def MOVXd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
+  def MOVXd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
+  def MOVXr32r16 : MxPseudoMove_RR<MxType32r, MxType16r>;
+}
 
 //===----------------------------------------------------------------------===//
 // Extend/Truncate Patterns
 //===----------------------------------------------------------------------===//
 
-// i16 <- sext i8
-def: Pat<(i16 (sext i8:$src)),
-          (EXTRACT_SUBREG (MOVSXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxSExtLoadi16i8 MxCP_ARI:$src),
-          (EXTRACT_SUBREG (MOVSXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxSExtLoadi16i8 MxCP_ARID:$src),
-          (EXTRACT_SUBREG (MOVSXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxSExtLoadi16i8 MxCP_ARII:$src),
-          (EXTRACT_SUBREG (MOVSXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxSExtLoadi16i8 MxCP_PCD:$src), (MOVSXd16q8 MxPCD8:$src)>;
-
-// i32 <- sext i8
+foreach AM = MxMoveSrcAMs in {
+  defvar OpB8 = !cast<MxOpBundle>("MxOp8AddrMode_"#AM);
+  defvar OpB16 = !cast<MxOpBundle>("MxOp16AddrMode_"#AM);
+  def : Pat<(MxSExtLoadi16i8 OpB8.Pat:$src),
+            (!cast<MxInst>("MOVSXd16"#AM#"8") OpB8.Op:$src)>;
+  def : Pat<(MxSExtLoadi32i8 OpB8.Pat:$src),
+            (!cast<MxInst>("MOVSXd32"#AM#"8") OpB8.Op:$src)>;
+  def : Pat<(MxSExtLoadi32i16 OpB16.Pat:$src),
+            (!cast<MxInst>("MOVSXr32"#AM#"16") OpB16.Op:$src)>;
+  def : Pat<(MxZExtLoadi16i8 OpB8.Pat:$src),
+            (!cast<MxInst>("MOVZXd16"#AM#"8") OpB8.Op:$src)>;
+  def : Pat<(MxZExtLoadi32i8 OpB8.Pat:$src),
+            (!cast<MxInst>("MOVZXd32"#AM#"8") OpB8.Op:$src)>;
+  def : Pat<(MxZExtLoadi32i16 OpB16.Pat:$src),
+            (!cast<MxInst>("MOVZXd32"#AM#"16") OpB16.Op:$src)>;
+  def : Pat<(MxExtLoadi16i8 OpB8.Pat:$src),
+            (!cast<MxInst>("MOVXd16"#AM#"8") OpB8.Op:$src)>;
+  def : Pat<(MxExtLoadi32i8 OpB8.Pat:$src),
+            (!cast<MxInst>("MOVXd32"#AM#"8") OpB8.Op:$src)>;
+  def : Pat<(MxExtLoadi32i16 OpB16.Pat:$src),
+            (!cast<MxInst>("MOVXr32"#AM#"16") OpB16.Op:$src)>;
+}
+
+def: Pat<(i16 (sext i8:$src)), (MOVSXd16d8 MxDRD8:$src)>;
 def: Pat<(i32 (sext i8:$src)), (MOVSXd32d8 MxDRD8:$src)>;
-def: Pat<(MxSExtLoadi32i8 MxCP_ARI :$src), (MOVSXd32j8 MxARI8 :$src)>;
-def: Pat<(MxSExtLoadi32i8 MxCP_ARID:$src), (MOVSXd32p8 MxARID8:$src)>;
-def: Pat<(MxSExtLoadi32i8 MxCP_ARII:$src), (MOVSXd32f8 MxARII8:$src)>;
-def: Pat<(MxSExtLoadi32i8 MxCP_PCD:$src),  (MOVSXd32q8 MxPCD8:$src)>;
-
-// i32 <- sext i16
-def: Pat<(i32 (sext i16:$src)), (MOVSXd32d16 MxDRD16:$src)>;
-def: Pat<(MxSExtLoadi32i16 MxCP_ARI :$src), (MOVSXd32j16 MxARI16 :$src)>;
-def: Pat<(MxSExtLoadi32i16 MxCP_ARID:$src), (MOVSXd32p16 MxARID16:$src)>;
-def: Pat<(MxSExtLoadi32i16 MxCP_ARII:$src), (MOVSXd32f16 MxARII16:$src)>;
-def: Pat<(MxSExtLoadi32i16 MxCP_PCD:$src),  (MOVSXd32q16 MxPCD16:$src)>;
-
-// i16 <- zext i8
-def: Pat<(i16 (zext i8:$src)),
-          (EXTRACT_SUBREG (MOVZXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxZExtLoadi16i8 MxCP_ARI:$src),
-          (EXTRACT_SUBREG (MOVZXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxZExtLoadi16i8 MxCP_ARID:$src),
-          (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxZExtLoadi16i8 MxCP_ARII:$src),
-          (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxZExtLoadi16i8 MxCP_PCD :$src), (MOVZXd16q8 MxPCD8 :$src)>;
-
-// i32 <- zext i8
+def: Pat<(i32 (sext i16:$src)), (MOVSXr32r16 MxXRD16:$src)>;
+def: Pat<(i16 (zext i8:$src)), (MOVZXd16d8 MxDRD8:$src)>;
 def: Pat<(i32 (zext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>;
-def: Pat<(MxZExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>;
-def: Pat<(MxZExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>;
-def: Pat<(MxZExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>;
-def: Pat<(MxZExtLoadi32i8 MxCP_PCD :$src), (MOVZXd32q8 MxPCD8 :$src)>;
-
-// i32 <- zext i16
-def: Pat<(i32 (zext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>;
-def: Pat<(MxZExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>;
-def: Pat<(MxZExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>;
-def: Pat<(MxZExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>;
-def: Pat<(MxZExtLoadi32i16 MxCP_PCD :$src), (MOVZXd32q16 MxPCD16 :$src)>;
-
-// i16 <- anyext i8
-def: Pat<(i16 (anyext i8:$src)),
-          (EXTRACT_SUBREG (MOVZXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxExtLoadi16i8 MxCP_ARI:$src),
-          (EXTRACT_SUBREG (MOVZXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxExtLoadi16i8 MxCP_ARID:$src),
-          (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxExtLoadi16i8 MxCP_ARII:$src),
-          (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
-def: Pat<(MxExtLoadi16i8 MxCP_PCD:$src),
-          (EXTRACT_SUBREG (MOVZXd32q8 MxPCD8:$src), MxSubRegIndex16Lo)>;
-
-// i32 <- anyext i8
-def: Pat<(i32 (anyext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>;
-def: Pat<(MxExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>;
-def: Pat<(MxExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>;
-def: Pat<(MxExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>;
-def: Pat<(MxExtLoadi32i8 MxCP_PCD:$src), (MOVZXd32q8 MxPCD8:$src)>;
-
-// i32 <- anyext i16
-def: Pat<(i32 (anyext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>;
-def: Pat<(MxExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>;
-def: Pat<(MxExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>;
-def: Pat<(MxExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>;
-def: Pat<(MxExtLoadi32i16 MxCP_PCD:$src), (MOVZXd32q16 MxPCD16:$src)>;
+def: Pat<(i32 (zext i16:$src)), (MOVZXd32r16 MxXRD16:$src)>;
+def: Pat<(i16 (anyext i8:$src)), (MOVXd16d8 MxDRD8:$src)>;
+def: Pat<(i32 (anyext i8:$src)), (MOVXd32d8 MxDRD8:$src)>;
+def: Pat<(i32 (anyext i16:$src)), (MOVXr32r16 MxXRD16:$src)>;
 
 // trunc patterns
 def : Pat<(i16 (trunc i32:$src)),
           (EXTRACT_SUBREG MxXRD32:$src, MxSubRegIndex16Lo)>;
 def : Pat<(i8  (trunc i32:$src)),
-          (EXTRACT_SUBREG MxXRD32:$src, MxSubRegIndex8Lo)>;
+          (EXTRACT_SUBREG MxDRD32:$src, MxSubRegIndex8Lo)>;
 def : Pat<(i8  (trunc i16:$src)),
-          (EXTRACT_SUBREG MxXRD16:$src, MxSubRegIndex8Lo)>;
+          (EXTRACT_SUBREG MxDRD16:$src, MxSubRegIndex8Lo)>;
 
 //===----------------------------------------------------------------------===//
 // FMOVE

diff  --git a/llvm/lib/Target/M68k/M68kInstrInfo.cpp b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
index 61693465af708..d4ebeab9b4b0a 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.cpp
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
@@ -435,7 +435,7 @@ bool M68kInstrInfo::ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const {
 
 bool M68kInstrInfo::ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst,
                                   MVT MVTSrc) const {
-  unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;
+  unsigned Move = MVTSrc == MVT::i8 ? M68k::MOV8dd : M68k::MOV16rr;
   Register Dst = MIB->getOperand(0).getReg();
   Register Src = MIB->getOperand(1).getReg();
 
@@ -450,19 +450,19 @@ bool M68kInstrInfo::ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst,
   assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVX_RR");
   (void)RCSrc;
 
-  // We need to find the super source register that matches the size of Dst
-  unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
-  assert(SSrc && "No viable MEGA register available");
+  unsigned SubDst =
+      RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
+                                          : M68k::MxSubRegIndex16Lo);
+  assert(SubDst && "No viable SUB register available");
 
-  // If it happens to that super source register is the destination register
-  // we do nothing
-  if (Dst == SSrc) {
+  // If source is a subregister of destination, we do nothing
+  if (SubDst == Src) {
     LLVM_DEBUG(dbgs() << "Remove " << *MIB.getInstr() << '\n');
     MIB->eraseFromParent();
   } else { // otherwise we need to MOV
     LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to MOV\n");
     MIB->setDesc(get(Move));
-    MIB->getOperand(1).setReg(SSrc);
+    MIB->getOperand(0).setReg(SubDst);
   }
 
   return true;
@@ -488,47 +488,53 @@ bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,
   assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVSX_RR");
   (void)RCSrc;
 
-  // We need to find the super source register that matches the size of Dst
-  unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
-  assert(SSrc && "No viable MEGA register available");
+  // Move source into subreg of the destination.
+  unsigned SubDst =
+      RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
+                                          : M68k::MxSubRegIndex16Lo);
+  assert(SubDst && "No viable SUB register available");
 
   MachineBasicBlock &MBB = *MIB->getParent();
   DebugLoc DL = MIB->getDebugLoc();
 
+  unsigned Move;
+  if (MVTSrc == MVT::i8)
+    Move = M68k::MOV8dd;
+  else
+    Move = M68k::MOV16rr;
+
   // It's more efficient to clear the destination and *then* move, rather than
   // move and zext.
-  if (Dst != SSrc && !IsSigned) {
+  if (SubDst != Src && !IsSigned) {
     LLVM_DEBUG(dbgs() << "Clear and Move" << '\n');
 
     buildClearRegister(Dst, MBB, MIB.getInstr(), DL);
 
-    if (MVTSrc == MVT::i8) {
-      unsigned SubDst = RI.getSubReg(Dst, M68k::MxSubRegIndex8Lo);
-      BuildMI(MBB, MIB.getInstr(), DL, get(M68k::MOV8dd), SubDst).addReg(Src);
-    } else { // i16
-      unsigned SubDst = RI.getSubReg(Dst, M68k::MxSubRegIndex16Lo);
-      BuildMI(MBB, MIB.getInstr(), DL, get(M68k::MOV16dd), SubDst).addReg(Src);
-    }
-  } else {
+    MIB->setDesc(get(Move));
+    MIB->getOperand(0).setReg(SubDst);
+    return true;
+  }
 
-    unsigned Move;
-    if (MVTDst == MVT::i16)
-      Move = M68k::MOV16dd;
-    else // i32
-      Move = M68k::MOV32dd;
+  // Special case where move to AR16 automatically sign-extends to 32 bits.
+  // Even an in-place move (move.w a0,a0) will do so.
+  if (M68k::AR32RegClass.contains(Dst) && IsSigned) {
+    LLVM_DEBUG(dbgs() << "Move (implicit Sign Extend)" << '\n');
+    MIB->setDesc(get(M68k::MOV16ar));
+    MIB->getOperand(0).setReg(SubDst);
+    return true;
+  }
 
-    if (Dst != SSrc) {
-      LLVM_DEBUG(dbgs() << "Move and " << '\n');
-      BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);
-    }
+  if (SubDst != Src) {
+    LLVM_DEBUG(dbgs() << "Move and " << '\n');
+    BuildMI(MBB, MIB.getInstr(), DL, get(Move), SubDst).addReg(Src);
+  }
 
-    if (IsSigned) {
-      LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
-      AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
-    } else {
-      LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
-      AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
-    }
+  if (IsSigned) {
+    LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
+    AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
+  } else {
+    LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
+    AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
   }
 
   MIB->eraseFromParent();
@@ -536,18 +542,35 @@ bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,
   return true;
 }
 
+bool M68kInstrInfo::ExpandMOVX_RM(MachineInstrBuilder &MIB, unsigned Opc,
+                                  MVT MVTDst, MVT MVTSrc) const {
+  LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD" << '\n');
+
+  const MCInstrDesc &Desc = get(Opc);
+  Register Dst = MIB->getOperand(0).getReg();
+
+  // Load source into subreg of the destination.
+  unsigned SubDst =
+      RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
+                                          : M68k::MxSubRegIndex16Lo);
+  assert(SubDst && "No viable SUB register available");
+
+  // Make this a plain move
+  MIB->setDesc(Desc);
+  MIB->getOperand(0).setReg(SubDst);
+
+  return true;
+}
+
 bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
-                                    const MCInstrDesc &Desc, MVT MVTDst,
+                                    unsigned Opc, MVT MVTDst,
                                     MVT MVTSrc) const {
   LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
 
+  const MCInstrDesc &Desc = get(Opc);
   Register Dst = MIB->getOperand(0).getReg();
 
-  // We need the subreg of Dst to make instruction verifier happy because the
-  // real machine instruction consumes and produces values of the same size and
-  // the registers the will be used here fall into 
diff erent classes and this
-  // makes IV cry. We could use a bigger operation, but this will put some
-  // pressure on cache and memory, so no.
+  // Load source into subreg of the destination.
   unsigned SubDst =
       RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
                                           : M68k::MxSubRegIndex16Lo);
@@ -557,6 +580,13 @@ bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
   MIB->setDesc(Desc);
   MIB->getOperand(0).setReg(SubDst);
 
+  // Special case where move to AR16 automatically sign-extends to 32 bits. In
+  // that case, we're already done.
+  if (M68k::AR32RegClass.contains(Dst) && IsSigned) {
+    LLVM_DEBUG(dbgs() << "LOAD (implicit Sign Extend)" << '\n');
+    return true;
+  }
+
   MachineBasicBlock::iterator I = MIB.getInstr();
   MachineBasicBlock &MBB = *MIB->getParent();
   DebugLoc DL = MIB->getDebugLoc();
@@ -755,16 +785,16 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
   // upper bits will be undefined.
   // 8 -> 16
   else if (M68k::DR8RegClass.contains(SrcReg) &&
-           M68k::XR16RegClass.contains(DstReg)) {
+           M68k::DR16RegClass.contains(DstReg)) {
     Opc = M68k::MOVXd16d8;
     // 8 -> 32
   } else if (M68k::DR8RegClass.contains(SrcReg) &&
-             M68k::XR32RegClass.contains(DstReg)) {
+             M68k::DR32RegClass.contains(DstReg)) {
     Opc = M68k::MOVXd32d8;
     // 16 -> 32
   } else if (M68k::XR16RegClass.contains(SrcReg) &&
              M68k::XR32RegClass.contains(DstReg)) {
-    Opc = M68k::MOVXd32d16;
+    Opc = M68k::MOVXr32r16;
   }
 
   // Copy from CCR

diff  --git a/llvm/lib/Target/M68k/M68kInstrInfo.h b/llvm/lib/Target/M68k/M68kInstrInfo.h
index a8148dd583380..1af261e64b5ef 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.h
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.h
@@ -312,9 +312,13 @@ class M68kInstrInfo : public M68kGenInstrInfo {
   bool ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, MVT MVTDst,
                        MVT MVTSrc) const;
 
+  /// Move from memory and expand register class without extension
+  bool ExpandMOVX_RM(MachineInstrBuilder &MIB, unsigned Opc, MVT MVTDst,
+                     MVT MVTSrc) const;
+
   /// Move from memory and extend
-  bool ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
-                       const MCInstrDesc &Desc, MVT MVTDst, MVT MVTSrc) const;
+  bool ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned, unsigned Opc,
+                       MVT MVTDst, MVT MVTSrc) const;
 
   /// Push/Pop to/from stack
   bool ExpandPUSH_POP(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,

diff  --git a/llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll b/llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll
index 65525efe01a8d..e2f9ac38ebd97 100644
--- a/llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll
+++ b/llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll
@@ -38,7 +38,7 @@ define zeroext i8 @test3(i8 zeroext %x, i8 zeroext %c) {
 ; CHECK-LABEL: test3:
 ; CHECK:         .cfi_startproc
 ; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    moveq #0, %d0
+; CHECK-NEXT:    clr.w %d0
 ; CHECK-NEXT:    move.b (11,%sp), %d0
 ; CHECK-NEXT:    muls #171, %d0
 ; CHECK-NEXT:    moveq #9, %d1
@@ -128,7 +128,7 @@ define i8 @test8(i8 %x) nounwind {
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    move.b (7,%sp), %d0
 ; CHECK-NEXT:    lsr.b #1, %d0
-; CHECK-NEXT:    and.l #255, %d0
+; CHECK-NEXT:    and.w #255, %d0
 ; CHECK-NEXT:    muls #211, %d0
 ; CHECK-NEXT:    moveq #13, %d1
 ; CHECK-NEXT:    lsr.w %d1, %d0
@@ -143,7 +143,7 @@ define i8 @test9(i8 %x) nounwind {
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    move.b (7,%sp), %d0
 ; CHECK-NEXT:    lsr.b #2, %d0
-; CHECK-NEXT:    and.l #255, %d0
+; CHECK-NEXT:    and.w #255, %d0
 ; CHECK-NEXT:    muls #71, %d0
 ; CHECK-NEXT:    moveq #11, %d1
 ; CHECK-NEXT:    lsr.w %d1, %d0

diff  --git a/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll b/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
index d10e1b12bd083..ed66043267c5c 100644
--- a/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
+++ b/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
@@ -4,13 +4,9 @@
 define zeroext i8 @smul_i8(i8 signext %a, i8 signext %b) nounwind ssp {
 ; CHECK-LABEL: smul_i8:
 ; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    moveq #0, %d0
-; CHECK-NEXT:    move.b (11,%sp), %d0
-; CHECK-NEXT:    moveq #0, %d1
-; CHECK-NEXT:    move.b (7,%sp), %d1
-; CHECK-NEXT:    muls %d0, %d1
-; CHECK-NEXT:    moveq #0, %d0
-; CHECK-NEXT:    move.w %d1, %d0
+; CHECK-NEXT:    move.b (7,%sp), %d0
+; CHECK-NEXT:    move.b (11,%sp), %d1
+; CHECK-NEXT:    muls %d1, %d0
 ; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    rts
 entry:

diff  --git a/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll b/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
index 42131dfa6b413..30f00fb95e8e6 100644
--- a/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
+++ b/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
@@ -4,13 +4,9 @@
 define zeroext i8 @umul_i8(i8 signext %a, i8 signext %b) nounwind ssp {
 ; CHECK-LABEL: umul_i8:
 ; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    moveq #0, %d0
-; CHECK-NEXT:    move.b (11,%sp), %d0
-; CHECK-NEXT:    moveq #0, %d1
-; CHECK-NEXT:    move.b (7,%sp), %d1
-; CHECK-NEXT:    muls %d0, %d1
-; CHECK-NEXT:    moveq #0, %d0
-; CHECK-NEXT:    move.w %d1, %d0
+; CHECK-NEXT:    move.b (7,%sp), %d0
+; CHECK-NEXT:    move.b (11,%sp), %d1
+; CHECK-NEXT:    muls %d1, %d0
 ; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    rts
 entry:

diff  --git a/llvm/test/CodeGen/M68k/Bits/btst.ll b/llvm/test/CodeGen/M68k/Bits/btst.ll
index 63eb07e961e42..cb3dd2e9956d4 100644
--- a/llvm/test/CodeGen/M68k/Bits/btst.ll
+++ b/llvm/test/CodeGen/M68k/Bits/btst.ll
@@ -7,9 +7,6 @@ define fastcc i16 @switch_to_btst(i16 %a) nounwind {
 ; CHECK-NEXT:    cmpi.w #11, %d0
 ; CHECK-NEXT:    bhi .LBB0_3
 ; CHECK-NEXT:  ; %bb.1: ; %entry
-; CHECK-NEXT:    swap %d0
-; CHECK-NEXT:    clr.w %d0
-; CHECK-NEXT:    swap %d0
 ; CHECK-NEXT:    move.l #3612, %d1
 ; CHECK-NEXT:    btst %d0, %d1
 ; CHECK-NEXT:    beq .LBB0_3

diff  --git a/llvm/test/CodeGen/M68k/Control/cmp.ll b/llvm/test/CodeGen/M68k/Control/cmp.ll
index 7988e44672dea..e4940ac919244 100644
--- a/llvm/test/CodeGen/M68k/Control/cmp.ll
+++ b/llvm/test/CodeGen/M68k/Control/cmp.ll
@@ -82,7 +82,6 @@ define i64 @test3(i64 %x) nounwind {
 ; CHECK-NEXT:    move.l (8,%sp), %d0
 ; CHECK-NEXT:    or.l (4,%sp), %d0
 ; CHECK-NEXT:    seq %d0
-; CHECK-NEXT:    moveq #0, %d1
 ; CHECK-NEXT:    move.b %d0, %d1
 ; CHECK-NEXT:    and.l #1, %d1
 ; CHECK-NEXT:    moveq #0, %d0
@@ -103,7 +102,6 @@ define i64 @test4(i64 %x) nounwind {
 ; CHECK-NEXT:    sub.l #1, %d2
 ; CHECK-NEXT:    subx.l %d0, %d1
 ; CHECK-NEXT:    slt %d1
-; CHECK-NEXT:    and.l #255, %d1
 ; CHECK-NEXT:    and.l #1, %d1
 ; CHECK-NEXT:    movem.l (0,%sp), %d2 ; 8-byte Folded Reload
 ; CHECK-NEXT:    adda.l #4, %sp
@@ -145,7 +143,6 @@ define i32 @test7(i64 %res) nounwind {
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    cmpi.l #0, (4,%sp)
 ; CHECK-NEXT:    seq %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    and.l #1, %d0
 ; CHECK-NEXT:    rts
 entry:
@@ -159,7 +156,6 @@ define i32 @test8(i64 %res) nounwind {
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    cmpi.l #3, (4,%sp)
 ; CHECK-NEXT:    scs %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    and.l #1, %d0
 ; CHECK-NEXT:    rts
 entry:
@@ -175,7 +171,6 @@ define i32 @test11(i64 %l) nounwind {
 ; CHECK-NEXT:    and.l #-32768, %d0
 ; CHECK-NEXT:    cmpi.l #32768, %d0
 ; CHECK-NEXT:    seq %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    and.l #1, %d0
 ; CHECK-NEXT:    rts
 entry:
@@ -241,7 +236,6 @@ define zeroext i1 @test15(i32 %bf.load, i32 %n) {
 ; CHECK-NEXT:    cmpi.l #0, %d1
 ; CHECK-NEXT:    seq %d1
 ; CHECK-NEXT:    or.b %d0, %d1
-; CHECK-NEXT:    moveq #0, %d0
 ; CHECK-NEXT:    move.b %d1, %d0
 ; CHECK-NEXT:    and.l #1, %d0
 ; CHECK-NEXT:    rts
@@ -296,7 +290,6 @@ define void @test20(i32 %bf.load, i8 %x1, ptr %b_addr) {
 ; CHECK-NEXT:    move.l #16777215, %d0
 ; CHECK-NEXT:    and.l (8,%sp), %d0
 ; CHECK-NEXT:    sne %d1
-; CHECK-NEXT:    and.l #255, %d1
 ; CHECK-NEXT:    and.l #1, %d1
 ; CHECK-NEXT:    moveq #0, %d2
 ; CHECK-NEXT:    move.b (15,%sp), %d2

diff  --git a/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll b/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
index 2ce75d380e51e..6efb6f7ca53f8 100644
--- a/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
+++ b/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
@@ -16,7 +16,6 @@ define internal void @select_i32(i32 %self, ptr nonnull %value) {
 ; M68000-NEXT:    move.w %d2, %ccr
 ; M68000-NEXT:    bne .LBB0_2
 ; M68000-NEXT:  ; %bb.1: ; %start
-; M68000-NEXT:    and.l #255, %d1
 ; M68000-NEXT:    and.l #1, %d1
 ; M68000-NEXT:    cmpi.l #0, %d1
 ; M68000-NEXT:    bne .LBB0_3
@@ -41,7 +40,6 @@ define internal void @select_i32(i32 %self, ptr nonnull %value) {
 ; M68020-NEXT:    move.w %d2, %ccr
 ; M68020-NEXT:    bne .LBB0_2
 ; M68020-NEXT:  ; %bb.1: ; %start
-; M68020-NEXT:    and.l #255, %d1
 ; M68020-NEXT:    and.l #1, %d1
 ; M68020-NEXT:    cmpi.l #0, %d1
 ; M68020-NEXT:    bne .LBB0_3
@@ -86,7 +84,6 @@ define internal void @select_i16(i16 %self, ptr nonnull %value) {
 ; M68000-NEXT:    move.w %d2, %ccr
 ; M68000-NEXT:    bne .LBB1_2
 ; M68000-NEXT:  ; %bb.1: ; %start
-; M68000-NEXT:    and.l #255, %d1
 ; M68000-NEXT:    and.w #1, %d1
 ; M68000-NEXT:    cmpi.w #0, %d1
 ; M68000-NEXT:    bne .LBB1_3
@@ -111,7 +108,6 @@ define internal void @select_i16(i16 %self, ptr nonnull %value) {
 ; M68020-NEXT:    move.w %d2, %ccr
 ; M68020-NEXT:    bne .LBB1_2
 ; M68020-NEXT:  ; %bb.1: ; %start
-; M68020-NEXT:    and.l #255, %d1
 ; M68020-NEXT:    and.w #1, %d1
 ; M68020-NEXT:    cmpi.w #0, %d1
 ; M68020-NEXT:    bne .LBB1_3

diff  --git a/llvm/test/CodeGen/M68k/Control/setcc.ll b/llvm/test/CodeGen/M68k/Control/setcc.ll
index 4be853b0067b4..73e0480bf94ce 100644
--- a/llvm/test/CodeGen/M68k/Control/setcc.ll
+++ b/llvm/test/CodeGen/M68k/Control/setcc.ll
@@ -8,7 +8,6 @@ define zeroext i16 @t1(i16 zeroext %x) nounwind readnone ssp {
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    cmpi.w #26, (6,%sp)
 ; CHECK-NEXT:    shi %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    and.l #1, %d0
 ; CHECK-NEXT:    lsl.l #5, %d0
 ; CHECK-NEXT:    rts
@@ -23,7 +22,6 @@ define zeroext i16 @t2(i16 zeroext %x) nounwind readnone ssp {
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    cmpi.w #26, (6,%sp)
 ; CHECK-NEXT:    scs %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    and.l #1, %d0
 ; CHECK-NEXT:    lsl.l #5, %d0
 ; CHECK-NEXT:    rts
@@ -42,7 +40,6 @@ define fastcc i64 @t3(i64 %x) nounwind readnone ssp {
 ; CHECK-NEXT:    sub.l #18, %d1
 ; CHECK-NEXT:    subx.l %d2, %d0
 ; CHECK-NEXT:    scs %d0
-; CHECK-NEXT:    moveq #0, %d1
 ; CHECK-NEXT:    move.b %d0, %d1
 ; CHECK-NEXT:    and.l #1, %d1
 ; CHECK-NEXT:    lsl.l #6, %d1

diff  --git a/llvm/test/CodeGen/M68k/Data/load-extend.ll b/llvm/test/CodeGen/M68k/Data/load-extend.ll
index 0a4d53643de29..fea7482ef9356 100644
--- a/llvm/test/CodeGen/M68k/Data/load-extend.ll
+++ b/llvm/test/CodeGen/M68k/Data/load-extend.ll
@@ -45,10 +45,8 @@ define i32 @"test_zext_pcd_i16_to_i32"() {
 define i16 @test_anyext_pcd_i8_to_i16() nounwind {
 ; CHECK-LABEL: test_anyext_pcd_i8_to_i16:
 ; CHECK:       ; %bb.0:
-; CHECK-NEXT:    moveq #0, %d0
 ; CHECK-NEXT:    move.b (__unnamed_1+4,%pc), %d0
 ; CHECK-NEXT:    lsl.w #8, %d0
-; CHECK-NEXT:    ; kill: def $wd0 killed $wd0 killed $d0
 ; CHECK-NEXT:    rts
   %copyload = load i8, ptr getelementptr inbounds nuw (i8, ptr @0, i32 4)
   %insert_ext = zext i8 %copyload to i16
@@ -60,7 +58,6 @@ define i32 @test_anyext_pcd_i8_to_i32() nounwind {
 ; CHECK-LABEL: test_anyext_pcd_i8_to_i32:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    moveq #24, %d1
-; CHECK-NEXT:    moveq #0, %d0
 ; CHECK-NEXT:    move.b (__unnamed_1+4,%pc), %d0
 ; CHECK-NEXT:    lsl.l %d1, %d0
 ; CHECK-NEXT:    rts
@@ -73,7 +70,6 @@ define i32 @test_anyext_pcd_i8_to_i32() nounwind {
 define i32 @test_anyext_pcd_i16_to_i32() nounwind {
 ; CHECK-LABEL: test_anyext_pcd_i16_to_i32:
 ; CHECK:       ; %bb.0:
-; CHECK-NEXT:    moveq #0, %d0
 ; CHECK-NEXT:    move.w (__unnamed_1+4,%pc), %d0
 ; CHECK-NEXT:    swap %d0
 ; CHECK-NEXT:    clr.w %d0

diff  --git a/llvm/test/CodeGen/M68k/Data/sext-i1.ll b/llvm/test/CodeGen/M68k/Data/sext-i1.ll
index a7f97fa5829ce..e35ab50846938 100644
--- a/llvm/test/CodeGen/M68k/Data/sext-i1.ll
+++ b/llvm/test/CodeGen/M68k/Data/sext-i1.ll
@@ -21,7 +21,6 @@ define void @sext_inreg_i1_to_i16(i1 %val, ptr %ptr) {
 ; CHECK-LABEL: sext_inreg_i1_to_i16:
 ; CHECK:         .cfi_startproc
 ; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    moveq #0, %d0
 ; CHECK-NEXT:    move.b (7,%sp), %d0
 ; CHECK-NEXT:    and.w #1, %d0
 ; CHECK-NEXT:    neg.w %d0
@@ -38,7 +37,6 @@ define void @sext_inreg_i1_to_i32(i1 %val, ptr %ptr) {
 ; CHECK-LABEL: sext_inreg_i1_to_i32:
 ; CHECK:         .cfi_startproc
 ; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    moveq #0, %d0
 ; CHECK-NEXT:    move.b (7,%sp), %d0
 ; CHECK-NEXT:    and.l #1, %d0
 ; CHECK-NEXT:    neg.l %d0

diff  --git a/llvm/test/CodeGen/M68k/register-spills.ll b/llvm/test/CodeGen/M68k/register-spills.ll
index 4055871632c93..c55da8fc9c97c 100644
--- a/llvm/test/CodeGen/M68k/register-spills.ll
+++ b/llvm/test/CodeGen/M68k/register-spills.ll
@@ -83,46 +83,30 @@ define void @test_force_spill_8() {
 ; CHECK-NEXT:    movem.w %d0, (68,%sp)
 ; CHECK-NEXT:    jsr get8
 ; CHECK-NEXT:    movem.w (66,%sp), %d1
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %sp, %a0
 ; CHECK-NEXT:    move.l %d0, (60,%a0)
 ; CHECK-NEXT:    movem.w (68,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (56,%a0)
 ; CHECK-NEXT:    movem.w (70,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (52,%a0)
 ; CHECK-NEXT:    movem.w (72,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (48,%a0)
 ; CHECK-NEXT:    movem.w (74,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (44,%a0)
 ; CHECK-NEXT:    movem.w (76,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (40,%a0)
 ; CHECK-NEXT:    movem.w (78,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (36,%a0)
 ; CHECK-NEXT:    movem.w (80,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (32,%a0)
 ; CHECK-NEXT:    movem.w (82,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d7
 ; CHECK-NEXT:    move.l %d7, (28,%a0)
-; CHECK-NEXT:    and.l #255, %d6
 ; CHECK-NEXT:    move.l %d6, (24,%a0)
-; CHECK-NEXT:    and.l #255, %d5
 ; CHECK-NEXT:    move.l %d5, (20,%a0)
-; CHECK-NEXT:    and.l #255, %d4
 ; CHECK-NEXT:    move.l %d4, (16,%a0)
-; CHECK-NEXT:    and.l #255, %d3
 ; CHECK-NEXT:    move.l %d3, (12,%a0)
-; CHECK-NEXT:    and.l #255, %d2
 ; CHECK-NEXT:    move.l %d2, (8,%a0)
-; CHECK-NEXT:    and.l #255, %d1
 ; CHECK-NEXT:    move.l %d1, (4,%a0)
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (%a0)
 ; CHECK-NEXT:    jsr test_force_spill_8_consumer
 ; CHECK-NEXT:    movem.l (84,%sp), %d2-%d7 ; 28-byte Folded Reload
@@ -191,60 +175,24 @@ define void @test_force_spill_16() {
 ; CHECK-NEXT:    jsr get16
 ; CHECK-NEXT:    movem.w (64,%sp), %a1
 ; CHECK-NEXT:    movem.w (66,%sp), %d1
-; CHECK-NEXT:    swap %d0
-; CHECK-NEXT:    clr.w %d0
-; CHECK-NEXT:    swap %d0
 ; CHECK-NEXT:    move.l %sp, %a0
 ; CHECK-NEXT:    move.l %d0, (60,%a0)
 ; CHECK-NEXT:    movem.w (68,%sp), %d0
-; CHECK-NEXT:    swap %d0
-; CHECK-NEXT:    clr.w %d0
-; CHECK-NEXT:    swap %d0
 ; CHECK-NEXT:    move.l %d0, (56,%a0)
 ; CHECK-NEXT:    movem.w (70,%sp), %d0
-; CHECK-NEXT:    and.l #65535, %a6
 ; CHECK-NEXT:    move.l %a6, (52,%a0)
-; CHECK-NEXT:    and.l #65535, %a5
 ; CHECK-NEXT:    move.l %a5, (48,%a0)
-; CHECK-NEXT:    and.l #65535, %a4
 ; CHECK-NEXT:    move.l %a4, (44,%a0)
-; CHECK-NEXT:    and.l #65535, %a3
 ; CHECK-NEXT:    move.l %a3, (40,%a0)
-; CHECK-NEXT:    and.l #65535, %a2
 ; CHECK-NEXT:    move.l %a2, (36,%a0)
-; CHECK-NEXT:    swap %d7
-; CHECK-NEXT:    clr.w %d7
-; CHECK-NEXT:    swap %d7
 ; CHECK-NEXT:    move.l %d7, (32,%a0)
-; CHECK-NEXT:    swap %d6
-; CHECK-NEXT:    clr.w %d6
-; CHECK-NEXT:    swap %d6
 ; CHECK-NEXT:    move.l %d6, (28,%a0)
-; CHECK-NEXT:    swap %d5
-; CHECK-NEXT:    clr.w %d5
-; CHECK-NEXT:    swap %d5
 ; CHECK-NEXT:    move.l %d5, (24,%a0)
-; CHECK-NEXT:    swap %d4
-; CHECK-NEXT:    clr.w %d4
-; CHECK-NEXT:    swap %d4
 ; CHECK-NEXT:    move.l %d4, (20,%a0)
-; CHECK-NEXT:    swap %d3
-; CHECK-NEXT:    clr.w %d3
-; CHECK-NEXT:    swap %d3
 ; CHECK-NEXT:    move.l %d3, (16,%a0)
-; CHECK-NEXT:    swap %d2
-; CHECK-NEXT:    clr.w %d2
-; CHECK-NEXT:    swap %d2
 ; CHECK-NEXT:    move.l %d2, (12,%a0)
-; CHECK-NEXT:    and.l #65535, %a1
 ; CHECK-NEXT:    move.l %a1, (8,%a0)
-; CHECK-NEXT:    swap %d1
-; CHECK-NEXT:    clr.w %d1
-; CHECK-NEXT:    swap %d1
 ; CHECK-NEXT:    move.l %d1, (4,%a0)
-; CHECK-NEXT:    swap %d0
-; CHECK-NEXT:    clr.w %d0
-; CHECK-NEXT:    swap %d0
 ; CHECK-NEXT:    move.l %d0, (%a0)
 ; CHECK-NEXT:    jsr test_force_spill_16_consumer
 ; CHECK-NEXT:    movem.l (72,%sp), %d2-%d7/%a2-%a6 ; 48-byte Folded Reload
@@ -407,61 +355,32 @@ define void @test_force_spill_mixed() {
 ; CHECK-NEXT:    jsr get16
 ; CHECK-NEXT:    movem.l (80,%sp), %a1
 ; CHECK-NEXT:    movem.w (86,%sp), %d1
-; CHECK-NEXT:    swap %d0
-; CHECK-NEXT:    clr.w %d0
-; CHECK-NEXT:    swap %d0
 ; CHECK-NEXT:    move.l %sp, %a0
 ; CHECK-NEXT:    move.l %d0, (76,%a0)
 ; CHECK-NEXT:    movem.l (88,%sp), %d0
 ; CHECK-NEXT:    move.l %d0, (72,%a0)
 ; CHECK-NEXT:    movem.w (94,%sp), %d0
-; CHECK-NEXT:    swap %d0
-; CHECK-NEXT:    clr.w %d0
-; CHECK-NEXT:    swap %d0
 ; CHECK-NEXT:    move.l %d0, (68,%a0)
 ; CHECK-NEXT:    movem.w (96,%sp), %d0
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (64,%a0)
 ; CHECK-NEXT:    movem.w (98,%sp), %d0
-; CHECK-NEXT:    swap %d0
-; CHECK-NEXT:    clr.w %d0
-; CHECK-NEXT:    swap %d0
 ; CHECK-NEXT:    move.l %d0, (60,%a0)
 ; CHECK-NEXT:    movem.w (100,%sp), %d0
 ; CHECK-NEXT:    move.l %a6, (56,%a0)
-; CHECK-NEXT:    and.l #65535, %a5
 ; CHECK-NEXT:    move.l %a5, (52,%a0)
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (48,%a0)
 ; CHECK-NEXT:    movem.w (102,%sp), %d0
-; CHECK-NEXT:    and.l #65535, %a4
 ; CHECK-NEXT:    move.l %a4, (44,%a0)
 ; CHECK-NEXT:    move.l %a3, (40,%a0)
-; CHECK-NEXT:    and.l #65535, %a2
 ; CHECK-NEXT:    move.l %a2, (36,%a0)
-; CHECK-NEXT:    and.l #255, %d7
 ; CHECK-NEXT:    move.l %d7, (32,%a0)
-; CHECK-NEXT:    swap %d6
-; CHECK-NEXT:    clr.w %d6
-; CHECK-NEXT:    swap %d6
 ; CHECK-NEXT:    move.l %d6, (28,%a0)
 ; CHECK-NEXT:    move.l %d5, (24,%a0)
-; CHECK-NEXT:    swap %d4
-; CHECK-NEXT:    clr.w %d4
-; CHECK-NEXT:    swap %d4
 ; CHECK-NEXT:    move.l %d4, (20,%a0)
-; CHECK-NEXT:    and.l #255, %d3
 ; CHECK-NEXT:    move.l %d3, (16,%a0)
-; CHECK-NEXT:    swap %d2
-; CHECK-NEXT:    clr.w %d2
-; CHECK-NEXT:    swap %d2
 ; CHECK-NEXT:    move.l %d2, (12,%a0)
 ; CHECK-NEXT:    move.l %a1, (8,%a0)
-; CHECK-NEXT:    swap %d1
-; CHECK-NEXT:    clr.w %d1
-; CHECK-NEXT:    swap %d1
 ; CHECK-NEXT:    move.l %d1, (4,%a0)
-; CHECK-NEXT:    and.l #255, %d0
 ; CHECK-NEXT:    move.l %d0, (%a0)
 ; CHECK-NEXT:    jsr test_force_spill_mixed_consumer
 ; CHECK-NEXT:    movem.l (104,%sp), %d2-%d7/%a2-%a6 ; 48-byte Folded Reload


        


More information about the llvm-commits mailing list