[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