[llvm] [AVR] Fix a bug of selecting inline assembly operand (PR #195066)

Ben Shi via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 30 05:23:44 PDT 2026


https://github.com/benshi001 created https://github.com/llvm/llvm-project/pull/195066

fixes https://github.com/llvm/llvm-project/issues/167244

>From e4cdb53f3df9d4730ac351ca8022af21485e5a54 Mon Sep 17 00:00:00 2001
From: Ben Shi <bennshi at tencent.com>
Date: Thu, 30 Apr 2026 20:21:55 +0800
Subject: [PATCH] [AVR] Fix a bug of selecting inline assembly operand

fixes https://github.com/llvm/llvm-project/issues/167244
---
 llvm/lib/Target/AVR/AVRAsmPrinter.cpp   |  8 +++++-
 llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp | 10 ++++++++
 llvm/test/CodeGen/AVR/issue-167244.ll   | 33 +++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/AVR/issue-167244.ll

diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
index 9aaf1e6c20103..cccca41694925 100644
--- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
+++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
@@ -162,7 +162,13 @@ bool AVRAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
     return true; // Unknown modifier
 
   const MachineOperand &MO = MI->getOperand(OpNum);
-  (void)MO;
+
+  // Print direct memory operands.
+  if (MO.isGlobal() || MO.isSymbol() || MO.isMCSymbol()) {
+    PrintSymbolOperand(MO, O);
+    return false;
+  }
+
   assert(MO.isReg() && "Unexpected inline asm memory operand");
 
   // TODO: We should be able to look up the alternative name for
diff --git a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp
index 20d35340bd15a..8997d0fb07dc3 100644
--- a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp
@@ -246,6 +246,16 @@ bool AVRDAGToDAGISel::SelectInlineAsmMemoryOperand(
     return true;
   }
 
+  // Select global addresses.
+  if (Op.getOpcode() == AVRISD::WRAPPER) {
+    SDValue Sub = Op.getOperand(0);
+    if (Sub.getOpcode() == ISD::TargetGlobalAddress &&
+        (Sub.getValueType() == MVT::i16 || Sub.getValueType() == MVT::i8)) {
+      OutOps.push_back(Sub);
+      return false;
+    }
+  }
+
   // If Op is add 'register, immediate' and
   // register is either virtual register or register of PTRDISPREGSRegClass
   if (Op->getOpcode() == ISD::ADD || Op->getOpcode() == ISD::SUB) {
diff --git a/llvm/test/CodeGen/AVR/issue-167244.ll b/llvm/test/CodeGen/AVR/issue-167244.ll
new file mode 100644
index 0000000000000..0967995a6936f
--- /dev/null
+++ b/llvm/test/CodeGen/AVR/issue-167244.ll
@@ -0,0 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=avr -mcpu=avr2 | FileCheck %s --check-prefix=AVR2
+; RUN: llc < %s -mtriple=avr -mcpu=avrtiny | FileCheck %s --check-prefix=TINY
+
+ at NVM = dso_local global i8 0, align 1
+
+define void @foo() addrspace(1) {
+; AVR2-LABEL: foo:
+; AVR2:       ; %bb.0: ; %entry
+; AVR2-NEXT:    sts NVM, r1
+; AVR2-NEXT:    ldi r24, 45
+; AVR2-NEXT:    ldi r25, 0
+; AVR2-NEXT:    ;APP
+; AVR2-NEXT:    sts NVM, r24
+; AVR2-NEXT:    lds r24, NVM
+; AVR2-NEXT:    ;NO_APP
+; AVR2-NEXT:    ret
+;
+; TINY-LABEL: foo:
+; TINY:       ; %bb.0: ; %entry
+; TINY-NEXT:    sts NVM, r17
+; TINY-NEXT:    ldi r24, 45
+; TINY-NEXT:    ldi r25, 0
+; TINY-NEXT:    ;APP
+; TINY-NEXT:    sts NVM, r24
+; TINY-NEXT:    lds r24, NVM
+; TINY-NEXT:    ;NO_APP
+; TINY-NEXT:    ret
+entry:
+  store i8 0, ptr @NVM, align 1
+  %0 = tail call addrspace(0) i8 asm "sts\09$1, $2\0Alds\09$0, $1", "=r,*m,r"(ptr nonnull elementtype(i8) @NVM, i16 45)
+  ret void
+}



More information about the llvm-commits mailing list