[llvm] [AVR] No cli for SPWRITE on XMEGA (PR #147210)

Tom Vijlbrief via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 13 12:13:47 PDT 2025


https://github.com/tomtor updated https://github.com/llvm/llvm-project/pull/147210

>From a0088b4bd3ccd93c0eeae9cbfdf355dea825d22c Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 6 Jul 2025 21:34:20 +0200
Subject: [PATCH 01/19] [AVR] No cli for SPWRITE on XMEGA

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 25 ++++++++++++++++----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 440d852fa4bc8..1c00010c76ff8 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2531,27 +2531,42 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   unsigned Flags = MI.getFlags();
   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
 
-  buildMI(MBB, MBBI, AVR::INRdA)
+  // From the XMEGA series manual:
+  // To prevent corruption when updating the stack pointer from software,
+  // a write to SPL will automatically disable interrupts
+  // for up to four instructions or until the next I/O memory write.
+  if (STI.getELFArch() >= 102) { // An XMEGA device
+    buildMI(MBB, MBBI, AVR::OUTARr)
+      .addImm(0x3d)
+      .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+      .setMIFlags(Flags);
+    buildMI(MBB, MBBI, AVR::OUTARr)
+      .addImm(0x3e)
+      .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+      .setMIFlags(Flags);
+  } else { // Disable interrupts for older devices (3 extra instructions)
+    buildMI(MBB, MBBI, AVR::INRdA)
       .addReg(STI.getTmpRegister(), RegState::Define)
       .addImm(STI.getIORegSREG())
       .setMIFlags(Flags);
 
-  buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
+    buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
 
-  buildMI(MBB, MBBI, AVR::OUTARr)
+    buildMI(MBB, MBBI, AVR::OUTARr)
       .addImm(0x3e)
       .addReg(SrcHiReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);
 
-  buildMI(MBB, MBBI, AVR::OUTARr)
+    buildMI(MBB, MBBI, AVR::OUTARr)
       .addImm(STI.getIORegSREG())
       .addReg(STI.getTmpRegister(), RegState::Kill)
       .setMIFlags(Flags);
 
-  buildMI(MBB, MBBI, AVR::OUTARr)
+    buildMI(MBB, MBBI, AVR::OUTARr)
       .addImm(0x3d)
       .addReg(SrcLoReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);
+  }
 
   MI.eraseFromParent();
   return true;

>From 065e8a3ff79776939f2af815bb1b2ca111312455 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 6 Jul 2025 21:56:08 +0200
Subject: [PATCH 02/19] formatting

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 40 +++++++++++---------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 1c00010c76ff8..23a50945bed88 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2536,36 +2536,40 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   // a write to SPL will automatically disable interrupts
   // for up to four instructions or until the next I/O memory write.
   if (STI.getELFArch() >= 102) { // An XMEGA device
+
     buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3d)
-      .addReg(SrcLoReg, getKillRegState(SrcIsKill))
-      .setMIFlags(Flags);
+        .addImm(0x3d)
+        .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
+
     buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3e)
-      .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-      .setMIFlags(Flags);
+        .addImm(0x3e)
+        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
+
   } else { // Disable interrupts for older devices (3 extra instructions)
+
     buildMI(MBB, MBBI, AVR::INRdA)
-      .addReg(STI.getTmpRegister(), RegState::Define)
-      .addImm(STI.getIORegSREG())
-      .setMIFlags(Flags);
+        .addReg(STI.getTmpRegister(), RegState::Define)
+        .addImm(STI.getIORegSREG())
+        .setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3e)
-      .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-      .setMIFlags(Flags);
+        .addImm(0x3e)
+        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(STI.getIORegSREG())
-      .addReg(STI.getTmpRegister(), RegState::Kill)
-      .setMIFlags(Flags);
+        .addImm(STI.getIORegSREG())
+        .addReg(STI.getTmpRegister(), RegState::Kill)
+        .setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3d)
-      .addReg(SrcLoReg, getKillRegState(SrcIsKill))
-      .setMIFlags(Flags);
+        .addImm(0x3d)
+        .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
   }
 
   MI.eraseFromParent();

>From 24afcd7c514fa153f9fe64e1f55c48e3ede49407 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 10:42:53 +0200
Subject: [PATCH 03/19] reorder

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 35 ++++++++------------
 1 file changed, 13 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 23a50945bed88..817684e9ee7df 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2535,42 +2535,33 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   // To prevent corruption when updating the stack pointer from software,
   // a write to SPL will automatically disable interrupts
   // for up to four instructions or until the next I/O memory write.
-  if (STI.getELFArch() >= 102) { // An XMEGA device
-
-    buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(0x3d)
-        .addReg(SrcLoReg, getKillRegState(SrcIsKill))
-        .setMIFlags(Flags);
-
-    buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(0x3e)
-        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-        .setMIFlags(Flags);
-
-  } else { // Disable interrupts for older devices (3 extra instructions)
+  //
+  // For old devices disable interrupts (3 extra instructions)
 
+  if (STI.getELFArch() < 102) { // Not an XMEGA device
     buildMI(MBB, MBBI, AVR::INRdA)
         .addReg(STI.getTmpRegister(), RegState::Define)
         .addImm(STI.getIORegSREG())
         .setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
+  }
 
-    buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(0x3e)
-        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-        .setMIFlags(Flags);
+  buildMI(MBB, MBBI, AVR::OUTARr)
+      .addImm(0x3d)
+      .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+      .setMIFlags(Flags);
 
+  if (STI.getELFArch() < 102) // Not an XMEGA device
     buildMI(MBB, MBBI, AVR::OUTARr)
         .addImm(STI.getIORegSREG())
         .addReg(STI.getTmpRegister(), RegState::Kill)
         .setMIFlags(Flags);
 
-    buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(0x3d)
-        .addReg(SrcLoReg, getKillRegState(SrcIsKill))
-        .setMIFlags(Flags);
-  }
+  buildMI(MBB, MBBI, AVR::OUTARr)
+      .addImm(0x3e)
+      .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+      .setMIFlags(Flags);
 
   MI.eraseFromParent();
   return true;

>From f80f924bf212e3938f2f552aedbbe3532472a6c9 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 11:04:00 +0200
Subject: [PATCH 04/19] no constants for SP location

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 817684e9ee7df..32cb19962cf23 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2548,7 +2548,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   }
 
   buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3d)
+      .addImm(STI.getIORegSPL())
       .addReg(SrcLoReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);
 
@@ -2559,7 +2559,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
         .setMIFlags(Flags);
 
   buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3e)
+      .addImm(STI.getIORegSPH())
       .addReg(SrcHiReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);
 

>From 2e7629e65a1333598c63a8cd8a0b753a1342dd42 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 11:27:53 +0200
Subject: [PATCH 05/19] Test and optimize for SPL only device

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 32cb19962cf23..eb0ebfa8634b7 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2538,7 +2538,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   //
   // For old devices disable interrupts (3 extra instructions)
 
-  if (STI.getELFArch() < 102) { // Not an XMEGA device
+  if (STI.getELFArch() < 102 && STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
     buildMI(MBB, MBBI, AVR::INRdA)
         .addReg(STI.getTmpRegister(), RegState::Define)
         .addImm(STI.getIORegSREG())
@@ -2558,7 +2558,8 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
         .addReg(STI.getTmpRegister(), RegState::Kill)
         .setMIFlags(Flags);
 
-  buildMI(MBB, MBBI, AVR::OUTARr)
+  if (STI.getIORegSPH() >= 0)
+    buildMI(MBB, MBBI, AVR::OUTARr)
       .addImm(STI.getIORegSPH())
       .addReg(SrcHiReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);

>From 28b238abb31eda84a3f8892d1d5e0f78cb128d79 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 11:33:25 +0200
Subject: [PATCH 06/19] Formatting for SPL only test

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index eb0ebfa8634b7..79313b147d6e7 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2538,7 +2538,8 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   //
   // For old devices disable interrupts (3 extra instructions)
 
-  if (STI.getELFArch() < 102 && STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
+  if (STI.getELFArch() < 102 &&
+      STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
     buildMI(MBB, MBBI, AVR::INRdA)
         .addReg(STI.getTmpRegister(), RegState::Define)
         .addImm(STI.getIORegSREG())
@@ -2560,9 +2561,9 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
 
   if (STI.getIORegSPH() >= 0)
     buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(STI.getIORegSPH())
-      .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-      .setMIFlags(Flags);
+        .addImm(STI.getIORegSPH())
+        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
 
   MI.eraseFromParent();
   return true;

>From 82c45cbe49059ff87f373b3b255303586f1b4d88 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 11:42:02 +0200
Subject: [PATCH 07/19] Another SPL only test

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 79313b147d6e7..79130c94fc55a 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2553,7 +2553,8 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
       .addReg(SrcLoReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);
 
-  if (STI.getELFArch() < 102) // Not an XMEGA device
+  if (STI.getELFArch() < 102 &&
+      STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
     buildMI(MBB, MBBI, AVR::OUTARr)
         .addImm(STI.getIORegSREG())
         .addReg(STI.getTmpRegister(), RegState::Kill)

>From 2a3a9507704efc64b9e6d152b1da4aca6aaa15ad Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 11:44:03 +0200
Subject: [PATCH 08/19] Fix another SPL only test

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 79130c94fc55a..bbb7c9fa7d9a3 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2554,7 +2554,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
       .setMIFlags(Flags);
 
   if (STI.getELFArch() < 102 &&
-      STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
+      STI.getIORegSPH() >= 0) // Not an XMEGA device and not just SPL
     buildMI(MBB, MBBI, AVR::OUTARr)
         .addImm(STI.getIORegSREG())
         .addReg(STI.getTmpRegister(), RegState::Kill)

>From d84f9188a0b44437167609b8848d8f6b95634561 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 14:47:32 +0200
Subject: [PATCH 09/19] Revert "Fix another SPL only test"

This reverts commit 2a3a9507704efc64b9e6d152b1da4aca6aaa15ad.
---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index bbb7c9fa7d9a3..79130c94fc55a 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2554,7 +2554,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
       .setMIFlags(Flags);
 
   if (STI.getELFArch() < 102 &&
-      STI.getIORegSPH() >= 0) // Not an XMEGA device and not just SPL
+      STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
     buildMI(MBB, MBBI, AVR::OUTARr)
         .addImm(STI.getIORegSREG())
         .addReg(STI.getTmpRegister(), RegState::Kill)

>From 4941e5ec43e4377d3e430215ca39c652df13a960 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 14:47:37 +0200
Subject: [PATCH 10/19] Revert "Another SPL only test"

This reverts commit 82c45cbe49059ff87f373b3b255303586f1b4d88.
---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 79130c94fc55a..79313b147d6e7 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2553,8 +2553,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
       .addReg(SrcLoReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);
 
-  if (STI.getELFArch() < 102 &&
-      STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
+  if (STI.getELFArch() < 102) // Not an XMEGA device
     buildMI(MBB, MBBI, AVR::OUTARr)
         .addImm(STI.getIORegSREG())
         .addReg(STI.getTmpRegister(), RegState::Kill)

>From 5f9604348740f772edda5176bad7ab7a987c8a44 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 14:47:39 +0200
Subject: [PATCH 11/19] Revert "Formatting for SPL only test"

This reverts commit 28b238abb31eda84a3f8892d1d5e0f78cb128d79.
---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 79313b147d6e7..eb0ebfa8634b7 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2538,8 +2538,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   //
   // For old devices disable interrupts (3 extra instructions)
 
-  if (STI.getELFArch() < 102 &&
-      STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
+  if (STI.getELFArch() < 102 && STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
     buildMI(MBB, MBBI, AVR::INRdA)
         .addReg(STI.getTmpRegister(), RegState::Define)
         .addImm(STI.getIORegSREG())
@@ -2561,9 +2560,9 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
 
   if (STI.getIORegSPH() >= 0)
     buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(STI.getIORegSPH())
-        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-        .setMIFlags(Flags);
+      .addImm(STI.getIORegSPH())
+      .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+      .setMIFlags(Flags);
 
   MI.eraseFromParent();
   return true;

>From 7a95adcf8686c8f48a5f16feb9f2078f59c0fc53 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 14:47:41 +0200
Subject: [PATCH 12/19] Revert "Test and optimize for SPL only device"

This reverts commit 2e7629e65a1333598c63a8cd8a0b753a1342dd42.
---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index eb0ebfa8634b7..32cb19962cf23 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2538,7 +2538,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   //
   // For old devices disable interrupts (3 extra instructions)
 
-  if (STI.getELFArch() < 102 && STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
+  if (STI.getELFArch() < 102) { // Not an XMEGA device
     buildMI(MBB, MBBI, AVR::INRdA)
         .addReg(STI.getTmpRegister(), RegState::Define)
         .addImm(STI.getIORegSREG())
@@ -2558,8 +2558,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
         .addReg(STI.getTmpRegister(), RegState::Kill)
         .setMIFlags(Flags);
 
-  if (STI.getIORegSPH() >= 0)
-    buildMI(MBB, MBBI, AVR::OUTARr)
+  buildMI(MBB, MBBI, AVR::OUTARr)
       .addImm(STI.getIORegSPH())
       .addReg(SrcHiReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);

>From 30cfc76a923c45ce2d172e9800f23bc57bba2d26 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 14:47:43 +0200
Subject: [PATCH 13/19] Revert "no constants for SP location"

This reverts commit f80f924bf212e3938f2f552aedbbe3532472a6c9.
---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 32cb19962cf23..817684e9ee7df 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2548,7 +2548,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   }
 
   buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(STI.getIORegSPL())
+      .addImm(0x3d)
       .addReg(SrcLoReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);
 
@@ -2559,7 +2559,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
         .setMIFlags(Flags);
 
   buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(STI.getIORegSPH())
+      .addImm(0x3e)
       .addReg(SrcHiReg, getKillRegState(SrcIsKill))
       .setMIFlags(Flags);
 

>From 42e0353de3147c0ed792130a3353763cdf98af9a Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 14:47:46 +0200
Subject: [PATCH 14/19] Revert "reorder"

This reverts commit 24afcd7c514fa153f9fe64e1f55c48e3ede49407.
---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 35 ++++++++++++--------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 817684e9ee7df..23a50945bed88 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2535,33 +2535,42 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   // To prevent corruption when updating the stack pointer from software,
   // a write to SPL will automatically disable interrupts
   // for up to four instructions or until the next I/O memory write.
-  //
-  // For old devices disable interrupts (3 extra instructions)
+  if (STI.getELFArch() >= 102) { // An XMEGA device
+
+    buildMI(MBB, MBBI, AVR::OUTARr)
+        .addImm(0x3d)
+        .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
+
+    buildMI(MBB, MBBI, AVR::OUTARr)
+        .addImm(0x3e)
+        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
+
+  } else { // Disable interrupts for older devices (3 extra instructions)
 
-  if (STI.getELFArch() < 102) { // Not an XMEGA device
     buildMI(MBB, MBBI, AVR::INRdA)
         .addReg(STI.getTmpRegister(), RegState::Define)
         .addImm(STI.getIORegSREG())
         .setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
-  }
 
-  buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3d)
-      .addReg(SrcLoReg, getKillRegState(SrcIsKill))
-      .setMIFlags(Flags);
+    buildMI(MBB, MBBI, AVR::OUTARr)
+        .addImm(0x3e)
+        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
 
-  if (STI.getELFArch() < 102) // Not an XMEGA device
     buildMI(MBB, MBBI, AVR::OUTARr)
         .addImm(STI.getIORegSREG())
         .addReg(STI.getTmpRegister(), RegState::Kill)
         .setMIFlags(Flags);
 
-  buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3e)
-      .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-      .setMIFlags(Flags);
+    buildMI(MBB, MBBI, AVR::OUTARr)
+        .addImm(0x3d)
+        .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
+  }
 
   MI.eraseFromParent();
   return true;

>From 72b3d4f2b88681e119c9c16d533d776bc49352e7 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 13 Jul 2025 10:19:09 +0200
Subject: [PATCH 15/19] use RegSPL/H instead of inline constants

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 23a50945bed88..94d0fa5eaede6 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2538,12 +2538,12 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   if (STI.getELFArch() >= 102) { // An XMEGA device
 
     buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(0x3d)
+        .addImm(STI.getIORegSPL())
         .addReg(SrcLoReg, getKillRegState(SrcIsKill))
         .setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(0x3e)
+        .addImm(STI.getIORegSPH())
         .addReg(SrcHiReg, getKillRegState(SrcIsKill))
         .setMIFlags(Flags);
 
@@ -2557,7 +2557,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
     buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(0x3e)
+        .addImm(STI.getIORegSPH())
         .addReg(SrcHiReg, getKillRegState(SrcIsKill))
         .setMIFlags(Flags);
 
@@ -2567,7 +2567,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
         .setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(0x3d)
+        .addImm(STI.getIORegSPL())
         .addReg(SrcLoReg, getKillRegState(SrcIsKill))
         .setMIFlags(Flags);
   }

>From ca0bf9a24bda45cbc30b98d7f93b92c70b3b9966 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 13 Jul 2025 16:51:10 +0200
Subject: [PATCH 16/19] Add tests and check to prevent write -1

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 94d0fa5eaede6..37c4c17a54b72 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2556,7 +2556,8 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
 
     buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
 
-    buildMI(MBB, MBBI, AVR::OUTARr)
+    if (STI.getIORegSPH() != -1)
+      buildMI(MBB, MBBI, AVR::OUTARr)
         .addImm(STI.getIORegSPH())
         .addReg(SrcHiReg, getKillRegState(SrcIsKill))
         .setMIFlags(Flags);

>From de13c77245dae32ec08e5084c12076c5b5288d4f Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 13 Jul 2025 16:58:54 +0200
Subject: [PATCH 17/19] Add tests and check to prevent write -1

---
 llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir | 48 ++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
 create mode 100644 llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir

diff --git a/llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir b/llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir
new file mode 100644
index 0000000000000..d24533ae85742
--- /dev/null
+++ b/llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir
@@ -0,0 +1,48 @@
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=attiny11 %s -o - \
+# RUN:     | FileCheck --check-prefix=NOSPH %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=atmega328 %s -o - \
+# RUN:     | FileCheck %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=attiny817 %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=atxmega64a1 %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=atxmega256a3u %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=attiny1614 %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=avr128db28 %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
+
+--- |
+  target triple = "avr--"
+  define void @test() {
+  entry:
+    ret void
+  }
+...
+
+---
+name:            test
+body: |
+  bb.0.entry:
+
+    ; CHECK-LABEL: test
+    ; CHECK:       $r0 = INRdA 63
+    ; CHECK:       BCLRs 7, implicit-def $sreg
+    ; CHECK:       OUTARr 62, $r15
+    ; CHECK:       OUTARr 63, killed $r0
+    ; CHECK:       OUTARr 61, $r14
+
+    ; NOSPH-LABEL: test
+    ; NOSPH:       $r0 = INRdA 63
+    ; NOSPH:       BCLRs 7, implicit-def $sreg
+    ; NOSPH:       OUTARr 63, killed $r0
+    ; NOSPH:       OUTARr 61, $r14
+
+
+    ; XMEGA-LABEL: test
+    ; XMEGA-LABEL: OUTARr 61, $r14
+    ; XMEGA-LABEL: OUTARr 62, $r15
+
+    $sp = SPWRITE implicit-def $sp, implicit $sp, $r15r14
+...

>From 27560165f4ea71e7f1c59d0e0c34b27007062e9f Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 13 Jul 2025 18:01:49 +0200
Subject: [PATCH 18/19] Format Add tests and check to prevent write -1

---
 llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 37c4c17a54b72..90505aa82aa46 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2558,9 +2558,9 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
 
     if (STI.getIORegSPH() != -1)
       buildMI(MBB, MBBI, AVR::OUTARr)
-        .addImm(STI.getIORegSPH())
-        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-        .setMIFlags(Flags);
+          .addImm(STI.getIORegSPH())
+          .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+          .setMIFlags(Flags);
 
     buildMI(MBB, MBBI, AVR::OUTARr)
         .addImm(STI.getIORegSREG())

>From 2fa1b4e9e4694a9c71f160ed0155b8069f84c804 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 13 Jul 2025 21:13:15 +0200
Subject: [PATCH 19/19] remove empty line

---
 llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir b/llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir
index d24533ae85742..ed6e39c641b11 100644
--- a/llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir
+++ b/llvm/test/CodeGen/AVR/pseudo/SPWRITE.mir
@@ -39,7 +39,6 @@ body: |
     ; NOSPH:       OUTARr 63, killed $r0
     ; NOSPH:       OUTARr 61, $r14
 
-
     ; XMEGA-LABEL: test
     ; XMEGA-LABEL: OUTARr 61, $r14
     ; XMEGA-LABEL: OUTARr 62, $r15



More information about the llvm-commits mailing list