[llvm-branch-commits] [llvm] [RISC-V][MC] Update ELF streamer ArchString when emitting RISCVAttrs::ARCH (PR #225140)

Alexander Richardson via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Sep 22 22:53:02 PDT 2026


https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/225140

>From 31c90c1575e85991a510344cef42ded94b06de96 Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Tue, 22 Sep 2026 22:52:25 -0700
Subject: [PATCH] [RISC-V][MC] Update ELF streamer ArchString when emitting
 RISCVAttrs::ARCH

During LTO, the TargetMachine subtarget is initialized with the linker's
default CPU (e.g. `generic-rv64`, `rv64i2p1`), while
RISCVAsmPrinter::emitStartOfAsmFile() reconstructs the module's actual ISA from
the `riscv-isa` module flag and emits RISCVAttrs::ARCH via
RISCVTargetELFStreamer::emitTextAttribute(). Previously only
RISCVAsmParser::parseDirectiveAttribute() called setArchString() after
emitTextAttribute(RISCVAttrs::ARCH, ...), so direct object emission bypassed
the update and tagged `.text` with `$xrv64i2p1` instead of the module's
full architecture string.

Move the setArchString() call into RISCVTargetELFStreamer::emitTextAttribute()
when emitting RISCVAttrs::ARCH so both `.attribute arch` and
RISCVTargetStreamer::emitTargetAttributes() update the active mapping symbol
ISA.

This commit was created with the help of AI tools
---
 .../riscv/lto-inline-asm-abi.c                | 19 ++++++++-----------
 .../Target/RISCV/AsmParser/RISCVAsmParser.cpp |  7 ++-----
 .../RISCV/MCTargetDesc/RISCVELFStreamer.cpp   |  6 ++++++
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/cross-project-tests/riscv/lto-inline-asm-abi.c b/cross-project-tests/riscv/lto-inline-asm-abi.c
index 883244f1854f7..897413428500f 100644
--- a/cross-project-tests/riscv/lto-inline-asm-abi.c
+++ b/cross-project-tests/riscv/lto-inline-asm-abi.c
@@ -35,33 +35,30 @@
 // FLAGS-NEXT:   EF_RISCV_RVC (0x1)
 // FLAGS-NEXT: ]
 //
-/// TODO: RISCVTargetELFStreamer::emitTextAttribute does not update the
-/// streamer's ArchString when emitting the module's RISCVAttrs::ARCH attribute
-/// ("rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_...").
 // DISASM-LABEL: Disassembly of section .text:
 // DISASM-EMPTY:
-// DISASM-NEXT:  [[#%x,]] <$xrv64i2p1>:
+// DISASM-NEXT:  [[#%x,]] <$xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0>:
 // DISASM-NEXT:  [[#%x,]]:      	nop
 // DISASM-EMPTY:
-// DISASM-NEXT:  [[#%x,]] <$xrv64i2p1>:
+// DISASM-NEXT:  [[#%x,]] <$xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0>:
 // DISASM-NEXT:  [[#%x,]] <symver_fn>:
 // DISASM-NEXT:  [[#%x,]]:      	ret
 // DISASM-EMPTY:
-// DISASM-NEXT:  [[#%x,]] <$xrv64i2p1>:
+// DISASM-NEXT:  [[#%x,]] <$xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0>:
 // DISASM-NEXT:  [[#%x,]] <fn>:
 // DISASM-NEXT:  [[#%x,]]:      	nop
 // DISASM-NEXT:  [[#%x,]]:      	ret
 // DISASM-EMPTY:
-// DISASM-NEXT:  [[#%x,]] <$xrv64i2p1>:
+// DISASM-NEXT:  [[#%x,]] <$xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0>:
 // DISASM-NEXT:  [[#%x,]] <caller>:
 // DISASM-NEXT:  [[#%x,]]:      	nop
 // DISASM-NEXT:  [[#%x,]]:      	ret
 // DISASM-NOT:   {{.}}
 //
-// SYMS: [[#%x,]] l       .text	0000000000000000 $xrv64i2p1{{$}}
-// SYMS: [[#%x,]] l       .text	0000000000000000 $xrv64i2p1{{$}}
-// SYMS: [[#%x,]] l       .text	0000000000000000 $xrv64i2p1{{$}}
-// SYMS: [[#%x,]] l       .text	0000000000000000 $xrv64i2p1{{$}}
+// SYMS: [[#%x,]] l       .text	0000000000000000 $xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0{{$}}
+// SYMS: [[#%x,]] l       .text	0000000000000000 $xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0{{$}}
+// SYMS: [[#%x,]] l       .text	0000000000000000 $xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0{{$}}
+// SYMS: [[#%x,]] l       .text	0000000000000000 $xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0{{$}}
 // SYMS: [[#%x,]] g     F .text	0000000000000004 fn{{$}}
 // SYMS: [[#%x,]] g     F .text	0000000000000002 symver_fn{{$}}
 // SYMS: [[#%x,]] g     F .text	0000000000000004 caller{{$}}
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index e9e8ffe6171f3..ccf5f14155dc4 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -3584,12 +3584,9 @@ bool RISCVAsmParser::parseDirectiveAttribute() {
     if (resetToArch(StringValue, ValueExprLoc, Result, false))
       return true;
 
-    // Then emit the arch string.
+    // Emit the arch string (which also updates the target streamer's active
+    // mapping symbol ISA).
     getTargetStreamer().emitTextAttribute(Tag, Result);
-
-    // And then update the active ISA so the next instruction-run emits
-    // an ISA-specific mapping symbol.
-    getTargetStreamer().setArchString(Result);
   }
 
   return false;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 0d83e30b495df..05b37d180025c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -21,6 +21,7 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/RISCVAttributes.h"
 
 using namespace llvm;
 
@@ -102,6 +103,11 @@ void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
                                                StringRef String) {
   getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
+  // Keep the active mapping symbol ISA in sync with .attribute arch and
+  // RISCVTargetStreamer::emitTargetAttributes() (e.g. when LTO reconstructs the
+  // module's ISA from the riscv-isa module flag).
+  if (Attribute == RISCVAttrs::ARCH)
+    setArchString(String);
 }
 
 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,



More information about the llvm-branch-commits mailing list