[llvm] [M68k] Do not allow addressing modes k and q as MOVE targets (llvm#200826) (PR #201653)

Michael Karcher via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 12 00:44:14 PDT 2026


https://github.com/karcherm updated https://github.com/llvm/llvm-project/pull/201653

>From e722fed2b8b048aff071183187f7d101a908bb5b Mon Sep 17 00:00:00 2001
From: "Michael.Karcher" <github at michael-karcher.net>
Date: Thu, 4 Jun 2026 19:51:24 +0200
Subject: [PATCH 1/2] [M68k] Do not allow addressing modes k and q as MOVE
 targets (#200826)

- Remove MOVE patterns that generate invalid M68k opcodes
- Remove atomic-store patterns that redirect to the invalild MOVE instructions
- Update tests to not expect invalid MOVE operands
---
 llvm/lib/Target/M68k/M68kInstrAtomics.td      |  8 ------
 llvm/lib/Target/M68k/M68kInstrData.td         | 27 ++++++++++---------
 .../CodeGen/M68k/CodeModel/Small/small-pic.ll |  5 ++--
 .../M68k/CodeModel/Small/small-static.ll      | 18 ++++++++-----
 llvm/test/CodeGen/M68k/Control/cmp.ll         |  7 ++---
 .../M68k/is-pcrel-register-operand-legal.mir  |  2 --
 6 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/llvm/lib/Target/M68k/M68kInstrAtomics.td b/llvm/lib/Target/M68k/M68kInstrAtomics.td
index b2b64ca853220..fe253f0b65394 100644
--- a/llvm/lib/Target/M68k/M68kInstrAtomics.td
+++ b/llvm/lib/Target/M68k/M68kInstrAtomics.td
@@ -33,14 +33,6 @@ foreach size = [8, 16, 32] in {
   def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_ARID:$ptr),
             (!cast<MxInst>("MOV"#size#"pd") !cast<MxMemOp>("MxARID"#size):$ptr,
                                             !cast<MxRegOp>("MxDRD"#size):$val)>;
-
-  def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_PCD:$ptr),
-            (!cast<MxInst>("MOV"#size#"qd") !cast<MxMemOp>("MxPCD"#size):$ptr,
-                                            !cast<MxRegOp>("MxDRD"#size):$val)>;                                   
-
-  def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_PCI:$ptr),
-            (!cast<MxInst>("MOV"#size#"kd") !cast<MxMemOp>("MxPCI"#size):$ptr,
-                                            !cast<MxRegOp>("MxDRD"#size):$val)>;                               
 }
 
 let Predicates = [AtLeastM68020] in {
diff --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td
index 7a579a9ddbdb1..fd654be09dc97 100644
--- a/llvm/lib/Target/M68k/M68kInstrData.td
+++ b/llvm/lib/Target/M68k/M68kInstrData.td
@@ -104,7 +104,8 @@ multiclass MxMoveOperandEncodings<string opnd_name> {
 defm Src : MxMoveOperandEncodings<"src">;
 defm Dst : MxMoveOperandEncodings<"dst">;
 
-defvar MxMoveSupportedAMs = ["o", "e", "k", "q", "f", "p", "b", "j"];
+defvar MxMoveSrcAMs = ["o", "e", "k", "q", "f", "p", "b", "j"];
+defvar MxMoveDstAMs = ["o", "e", "f", "p", "b", "j"];
 
 let Defs = [CCR] in
 class MxMove<string size, dag outs, dag ins, list<dag> pattern, MxMoveEncoding enc>
@@ -150,7 +151,7 @@ class MxMove_MI<MxType TYPE, MxOpBundle DST, MxMoveEncoding ENC,
 } // let mayStore = 1
 
 foreach REG = ["r", "a", "d"] in
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveDstAMs in {
   foreach TYPE = !if(!eq(REG, "d"), [MxType8, MxType16, MxType32], [MxType16, MxType32]) in
   def MOV # TYPE.Size # AM # REG # TYPE.Postfix
       : MxMove_MR<TYPE, !cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#AM), REG,
@@ -159,7 +160,7 @@ foreach AM = MxMoveSupportedAMs in {
                                  !cast<MxEncMemOp>("MxMoveSrcOpEnc_"#REG)>>;
 } // foreach AM
 
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveDstAMs in {
   foreach TYPE = [MxType8, MxType16, MxType32] in
   def MOV # TYPE.Size # AM # i # TYPE.Postfix
       : MxMove_MI<TYPE, !cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#AM),
@@ -196,7 +197,7 @@ class MxMove_RM<MxType TYPE, string DST_REG, MxOpBundle SRC, MxEncMemOp SRC_ENC,
              MxMoveEncoding<SIZE_ENC, DST_ENC, SRC_ENC>>;
 
 foreach REG = ["r", "a", "d"] in
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveSrcAMs in {
   foreach TYPE = !if(!eq(REG, "d"), [MxType8, MxType16, MxType32], [MxType16, MxType32]) in
   def MOV # TYPE.Size # REG # AM # TYPE.Postfix
       : MxMove_RM<TYPE, REG, !cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#AM),
@@ -206,7 +207,7 @@ foreach AM = MxMoveSupportedAMs in {
 // Tail call version
 let Pattern = [(null_frag)] in {
   foreach REG = ["r", "a"] in
-  foreach AM = MxMoveSupportedAMs in {
+  foreach AM = MxMoveSrcAMs in {
     foreach TYPE = [MxType16, MxType32] in
     def MOV # TYPE.Size # REG # AM # _TC
         : MxMove_RM<TYPE, REG, !cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#AM),
@@ -234,8 +235,8 @@ class MxMove_MM_Safe<MxType TYPE, PatFrag StoreLoad,
              MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#TYPE.Size),
                             DST_ENC, SRC_ENC>>;
 
-foreach DST_AM = MxMoveSupportedAMs in
-foreach SRC_AM = MxMoveSupportedAMs in {
+foreach DST_AM = MxMoveDstAMs in
+foreach SRC_AM = MxMoveSrcAMs in {
   def MOV8 # DST_AM # SRC_AM # !cast<MxType>("MxType8").Postfix
       : MxMove_MM_Safe<MxType8, Mxstoreloadi8_safe,
                        !cast<MxOpBundle>("MxOp8AddrMode_"#DST_AM),
@@ -331,7 +332,7 @@ class MxMOVEM_MR<MxType TYPE, bit SIZE_ENC,
   let Inst = MxMOVEMEncoding<MEM_ENC, SIZE_ENC, MxMOVEM_MR, "mask">.Value;
 }
 
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveDstAMs in {
   foreach TYPE = [MxType16, MxType32] in
   def MOVM # TYPE.Size # AM # m # TYPE.Postfix
       : MxMOVEM_MR<TYPE, !if(!eq(TYPE, MxType16), MxMOVEM_W, MxMOVEM_L),
@@ -349,7 +350,7 @@ class MxMOVEM_RM<MxType TYPE, bit SIZE_ENC,
   let Inst = MxMOVEMEncoding<MEM_ENC, SIZE_ENC, MxMOVEM_RM, "mask">.Value;
 }
 
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveSrcAMs in {
   foreach TYPE = [MxType16, MxType32] in
   def MOVM # TYPE.Size # m # AM # TYPE.Postfix
       : MxMOVEM_RM<TYPE, !if(!eq(TYPE, MxType16), MxMOVEM_W, MxMOVEM_L),
@@ -408,7 +409,7 @@ class MxMoveToCCRPseudo<MxOperand MEMOp>
 } // let Defs = [CCR]
 
 let mayLoad = 1 in
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveSrcAMs in {
   def MOV16c # AM : MxMoveToCCR<!cast<MxOpBundle>("MxOp16AddrMode_"#AM).Op,
                                 !cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM)>;
   def MOV8c # AM  : MxMoveToCCRPseudo<!cast<MxOpBundle>("MxOp8AddrMode_"#AM).Op>;
@@ -447,7 +448,7 @@ class MxMoveFromCCR_RPseudo<MxOperand MEMOp>
 } // let Uses = [CCR]
 
 let mayStore = 1 in
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveDstAMs in {
   def MOV16 # AM # c
     : MxMoveFromCCR_M<!cast<MxOpBundle>("MxOp16AddrMode_"#AM).Op,
                       !cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM)>;
@@ -476,7 +477,7 @@ class MxMoveToSR<MxOperand MEMOp, MxEncMemOp SRC_ENC>
 } // let Defs = [SR]
 
 let mayLoad = 1 in
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveSrcAMs in {
   def MOV16s # AM : MxMoveToSR<!cast<MxOpBundle>("MxOp16AddrMode_"#AM).Op,
                                 !cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM)>;
 } // foreach AM
@@ -506,7 +507,7 @@ class MxMoveFromSR_M<MxOperand MEMOp, MxEncMemOp DST_ENC>
 } // let Uses = [SR]
 
 let mayStore = 1 in
-foreach AM = MxMoveSupportedAMs in {
+foreach AM = MxMoveDstAMs in {
   def MOV16 # AM # s
     : MxMoveFromSR_M<!cast<MxOpBundle>("MxOp16AddrMode_"#AM).Op,
                       !cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM)>;
diff --git a/llvm/test/CodeGen/M68k/CodeModel/Small/small-pic.ll b/llvm/test/CodeGen/M68k/CodeModel/Small/small-pic.ll
index 37115953e5be3..04a42689cb281 100644
--- a/llvm/test/CodeGen/M68k/CodeModel/Small/small-pic.ll
+++ b/llvm/test/CodeGen/M68k/CodeModel/Small/small-pic.ll
@@ -101,8 +101,9 @@ define void @test5() nounwind {
 ; CHECK-LABEL: test5:
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    lea (dst6,%pc), %a0
-; CHECK-NEXT:    move.l %a0, (ptr6,%pc)
-; CHECK-NEXT:    move.l (src6,%pc), (dst6,%pc)
+; CHECK-NEXT:    lea (ptr6,%pc), %a1
+; CHECK-NEXT:    move.l %a0, (%a1)
+; CHECK-NEXT:    move.l (src6,%pc), (%a0)
 ; CHECK-NEXT:    rts
 entry:
     store ptr @dst6, ptr @ptr6
diff --git a/llvm/test/CodeGen/M68k/CodeModel/Small/small-static.ll b/llvm/test/CodeGen/M68k/CodeModel/Small/small-static.ll
index 1b946c19b250f..5c479979d68a7 100644
--- a/llvm/test/CodeGen/M68k/CodeModel/Small/small-static.ll
+++ b/llvm/test/CodeGen/M68k/CodeModel/Small/small-static.ll
@@ -11,8 +11,9 @@ define void @test0() nounwind {
 ; CHECK-LABEL: test0:
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    lea (dst,%pc), %a0
-; CHECK-NEXT:    move.l %a0, (ptr,%pc)
-; CHECK-NEXT:    move.l (src,%pc), (dst,%pc)
+; CHECK-NEXT:    lea (ptr,%pc), %a1
+; CHECK-NEXT:    move.l %a0, (%a1)
+; CHECK-NEXT:    move.l (src,%pc), (%a0)
 ; CHECK-NEXT:    rts
 entry:
     store ptr @dst, ptr @ptr
@@ -29,8 +30,9 @@ define void @test1() nounwind {
 ; CHECK-LABEL: test1:
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    lea (dst2,%pc), %a0
-; CHECK-NEXT:    move.l %a0, (ptr2,%pc)
-; CHECK-NEXT:    move.l (src2,%pc), (dst2,%pc)
+; CHECK-NEXT:    lea (ptr2,%pc), %a1
+; CHECK-NEXT:    move.l %a0, (%a1)
+; CHECK-NEXT:    move.l (src2,%pc), (%a0)
 ; CHECK-NEXT:    rts
 entry:
     store ptr @dst2, ptr @ptr2
@@ -62,7 +64,8 @@ define void @test3() nounwind {
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    suba.l #4, %sp
 ; CHECK-NEXT:    jsr afoo
-; CHECK-NEXT:    move.l %a0, (pfoo,%pc)
+; CHECK-NEXT:    lea (pfoo,%pc), %a1
+; CHECK-NEXT:    move.l %a0, (%a1)
 ; CHECK-NEXT:    jsr (%a0)
 ; CHECK-NEXT:    adda.l #4, %sp
 ; CHECK-NEXT:    rts
@@ -96,8 +99,9 @@ define void @test5() nounwind {
 ; CHECK-LABEL: test5:
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    lea (dst6,%pc), %a0
-; CHECK-NEXT:    move.l %a0, (ptr6,%pc)
-; CHECK-NEXT:    move.l (src6,%pc), (dst6,%pc)
+; CHECK-NEXT:    lea (ptr6,%pc), %a1
+; CHECK-NEXT:    move.l %a0, (%a1)
+; CHECK-NEXT:    move.l (src6,%pc), (%a0)
 ; CHECK-NEXT:    rts
 entry:
     store ptr @dst6, ptr @ptr6
diff --git a/llvm/test/CodeGen/M68k/Control/cmp.ll b/llvm/test/CodeGen/M68k/Control/cmp.ll
index 01dfaeb1b2ec2..ae78534df4cd5 100644
--- a/llvm/test/CodeGen/M68k/Control/cmp.ll
+++ b/llvm/test/CodeGen/M68k/Control/cmp.ll
@@ -294,7 +294,7 @@ define void @test20(i32 %bf.load, i8 %x1, ptr %b_addr) {
 ; CHECK-NEXT:  ; %bb.0:
 ; CHECK-NEXT:    suba.l #4, %sp
 ; CHECK-NEXT:    .cfi_def_cfa_offset -8
-; CHECK-NEXT:    movem.l %d2, (0,%sp)                    ; 8-byte Folded Spill
+; CHECK-NEXT:    movem.l %d2, (0,%sp) ; 8-byte Folded Spill
 ; CHECK-NEXT:    move.l #16777215, %d0
 ; CHECK-NEXT:    and.l (8,%sp), %d0
 ; CHECK-NEXT:    sne %d1
@@ -310,8 +310,9 @@ define void @test20(i32 %bf.load, i8 %x1, ptr %b_addr) {
 ; CHECK-NEXT:    cmpi.l #0, %d0
 ; CHECK-NEXT:    sne %d0
 ; CHECK-NEXT:    and.b #1, %d0
-; CHECK-NEXT:    move.b %d0, (d,%pc)
-; CHECK-NEXT:    movem.l (0,%sp), %d2                    ; 8-byte Folded Reload
+; CHECK-NEXT:    lea (d,%pc), %a0
+; CHECK-NEXT:    move.b %d0, (%a0)
+; CHECK-NEXT:    movem.l (0,%sp), %d2 ; 8-byte Folded Reload
 ; CHECK-NEXT:    adda.l #4, %sp
 ; CHECK-NEXT:    rts
   %bf.shl = shl i32 %bf.load, 8
diff --git a/llvm/test/CodeGen/M68k/is-pcrel-register-operand-legal.mir b/llvm/test/CodeGen/M68k/is-pcrel-register-operand-legal.mir
index a755164937b16..3e2adff67744a 100644
--- a/llvm/test/CodeGen/M68k/is-pcrel-register-operand-legal.mir
+++ b/llvm/test/CodeGen/M68k/is-pcrel-register-operand-legal.mir
@@ -4,7 +4,5 @@ name: is-pcrel-register-operand-legal
 body:             |
   bb.0.entry:
     ; CHECK: move.l  (0,%pc,%a0), (%a1)
-    ; CHECK: move.l  (%a0), (0,%pc,%a1)
 
     MOV32jk $a1,  0, $a0, implicit-def $ccr
-    MOV32kj 0,  $a1, $a0, implicit-def $ccr
\ No newline at end of file

>From 663e9bb768c985af88ae474ab163858c3c5deec3 Mon Sep 17 00:00:00 2001
From: "Michael.Karcher" <github at michael-karcher.net>
Date: Fri, 12 Jun 2026 09:42:27 +0200
Subject: [PATCH 2/2] [M68k] Add test for atomic PC-relative store

---
 llvm/test/CodeGen/M68k/Atomics/load-store.ll | 21 ++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/llvm/test/CodeGen/M68k/Atomics/load-store.ll b/llvm/test/CodeGen/M68k/Atomics/load-store.ll
index 8ed3ae81d0920..adb715eb8d327 100644
--- a/llvm/test/CodeGen/M68k/Atomics/load-store.ll
+++ b/llvm/test/CodeGen/M68k/Atomics/load-store.ll
@@ -684,3 +684,24 @@ start:
 exit:                                              ; preds = %start
   ret i32 %2
 }
+
+ at dst = external global i32
+
+define void @test0() nounwind {
+; NO-ATOMIC-LABEL: test0:
+; NO-ATOMIC:       ; %bb.0: ; %entry
+; NO-ATOMIC-NEXT:    moveq #0, %d0
+; NO-ATOMIC-NEXT:    lea (dst,%pc), %a0
+; NO-ATOMIC-NEXT:    move.l %d0, (%a0)
+; NO-ATOMIC-NEXT:    rts
+;
+; ATOMIC-LABEL: test0:
+; ATOMIC:       ; %bb.0: ; %entry
+; ATOMIC-NEXT:    moveq #0, %d0
+; ATOMIC-NEXT:    lea (dst,%pc), %a0
+; ATOMIC-NEXT:    move.l %d0, (%a0)
+; ATOMIC-NEXT:    rts
+entry:
+    store atomic i32 0, ptr @dst unordered, align 4
+    ret void
+}



More information about the llvm-commits mailing list