From b9180d6b5b7df1259cac90986cd7f392563b2349 Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Mon, 1 Jul 2024 13:55:00 -0700 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 [skip ci] --- llvm/include/llvm/Support/RISCVAttributeParser.h | 1 + llvm/include/llvm/Support/RISCVAttributes.h | 11 +++++++++++ llvm/lib/Support/RISCVAttributeParser.cpp | 13 ++++++++++++- llvm/lib/Support/RISCVAttributes.cpp | 1 + .../RISCV/MCTargetDesc/RISCVTargetStreamer.cpp | 16 ++++++++++++++++ llvm/test/CodeGen/RISCV/attributes.ll | 10 +++++++++- llvm/test/MC/RISCV/attribute.s | 3 +++ llvm/test/MC/RISCV/invalid-attribute.s | 3 +++ 8 files changed, 56 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/Support/RISCVAttributeParser.h b/llvm/include/llvm/Support/RISCVAttributeParser.h index 305adffbe851e..9f295504de959 100644 --- a/llvm/include/llvm/Support/RISCVAttributeParser.h +++ b/llvm/include/llvm/Support/RISCVAttributeParser.h @@ -24,6 +24,7 @@ class RISCVAttributeParser : public ELFAttributeParser { Error unalignedAccess(unsigned tag); Error stackAlign(unsigned tag); + Error atomicAbi(unsigned tag); public: RISCVAttributeParser(ScopedPrinter *sw) diff --git a/llvm/include/llvm/Support/RISCVAttributes.h b/llvm/include/llvm/Support/RISCVAttributes.h index 18f5a84d21f25..07476e818cb77 100644 --- a/llvm/include/llvm/Support/RISCVAttributes.h +++ b/llvm/include/llvm/Support/RISCVAttributes.h @@ -32,6 +32,17 @@ enum AttrType : unsigned { PRIV_SPEC = 8, PRIV_SPEC_MINOR = 10, PRIV_SPEC_REVISION = 12, + ATOMIC_ABI = 14, +}; + +enum class RISCVAtomicAbiTag : unsigned { + // Values for Tag_RISCV_atomic_abi + // Defined at + // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#tag_riscv_atomic_abi-14-uleb128version + UNKNOWN = 0, + A6C = 1, + A6S = 2, + A7 = 3, }; enum { NOT_ALLOWED = 0, ALLOWED = 1 }; diff --git a/llvm/lib/Support/RISCVAttributeParser.cpp b/llvm/lib/Support/RISCVAttributeParser.cpp index 7ce4b6ab161cd..19c5a0e06903f 100644 --- a/llvm/lib/Support/RISCVAttributeParser.cpp +++ b/llvm/lib/Support/RISCVAttributeParser.cpp @@ -36,7 +36,18 @@ const RISCVAttributeParser::DisplayHandler { RISCVAttrs::UNALIGNED_ACCESS, &RISCVAttributeParser::unalignedAccess, - }}; + }, + { + RISCVAttrs::ATOMIC_ABI, + &RISCVAttributeParser::atomicAbi, + }, +}; + +Error RISCVAttributeParser::atomicAbi(unsigned Tag) { + uint64_t Value = de.getULEB128(cursor); + printAttribute(Tag, Value, "Atomic ABI is " + utostr(Value)); + return Error::success(); +} Error RISCVAttributeParser::unalignedAccess(unsigned tag) { static const char *strings[] = {"No unaligned access", "Unaligned access"}; diff --git a/llvm/lib/Support/RISCVAttributes.cpp b/llvm/lib/Support/RISCVAttributes.cpp index 9e629760d3d84..dc70d65acba06 100644 --- a/llvm/lib/Support/RISCVAttributes.cpp +++ b/llvm/lib/Support/RISCVAttributes.cpp @@ -18,6 +18,7 @@ static constexpr TagNameItem tagData[] = { {PRIV_SPEC, "Tag_priv_spec"}, {PRIV_SPEC_MINOR, "Tag_priv_spec_minor"}, {PRIV_SPEC_REVISION, "Tag_priv_spec_revision"}, + {ATOMIC_ABI, "Tag_atomic_abi"}, }; constexpr TagNameMap RISCVAttributeTags{tagData}; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp index 0f92e9ed6a64d..edc4d72d6b434 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -14,12 +14,20 @@ #include "RISCVBaseInfo.h" #include "RISCVMCTargetDesc.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/RISCVAttributes.h" #include "llvm/TargetParser/RISCVISAInfo.h" using namespace llvm; +// This option controls wether or not we emit ELF attributes for ABI features, +// like RISC-V atomics or X3 usage. +static cl::opt RiscvAbiAttr( + "riscv-abi-attributes", + cl::desc("Enable emitting RISC-V ELF attributes for ABI features"), + cl::init(false), cl::Hidden); + RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} void RISCVTargetStreamer::finish() { finishAttributeSection(); } @@ -75,6 +83,14 @@ void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI, auto &ISAInfo = *ParseResult; emitTextAttribute(RISCVAttrs::ARCH, ISAInfo->toString()); } + + if (RiscvAbiAttr && STI.hasFeature(RISCV::FeatureStdExtA)) { + unsigned AtomicABITag = + static_cast(STI.hasFeature(RISCV::FeatureTrailingSeqCstFence) + ? RISCVAttrs::RISCVAtomicAbiTag::A6S + : RISCVAttrs::RISCVAtomicAbiTag::A6C); + emitAttribute(RISCVAttrs::ATOMIC_ABI, AtomicABITag); + } } // This part is for ascii assembly output diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index 135baad04bbbd..292a2856ed8f5 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -135,7 +135,8 @@ ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s ; RUN: llc -mtriple=riscv64 -mattr=+zmmul %s -o - | FileCheck --check-prefixes=CHECK,RV64ZMMUL %s ; RUN: llc -mtriple=riscv64 -mattr=+m,+zmmul %s -o - | FileCheck --check-prefixes=CHECK,RV64MZMMUL %s -; RUN: llc -mtriple=riscv64 -mattr=+a %s -o - | FileCheck --check-prefixes=CHECK,RV64A %s +; RUN: llc -mtriple=riscv64 -mattr=+a --riscv-abi-attributes %s -o - | FileCheck --check-prefixes=CHECK,RV64A,A6C %s +; RUN: llc -mtriple=riscv64 -mattr=+a,+seq-cst-trailing-fence --riscv-abi-attributes %s -o - | FileCheck --check-prefixes=CHECK,RV64A,A6S %s ; RUN: llc -mtriple=riscv64 -mattr=+b %s -o - | FileCheck --check-prefixes=CHECK,RV64B %s ; RUN: llc -mtriple=riscv64 -mattr=+f %s -o - | FileCheck --check-prefixes=CHECK,RV64F %s ; RUN: llc -mtriple=riscv64 -mattr=+d %s -o - | FileCheck --check-prefixes=CHECK,RV64D %s @@ -565,3 +566,10 @@ define i32 @addi(i32 %a) { %1 = add i32 %a, 1 ret i32 %1 } + +define i8 @atomic_load_i8_seq_cst(ptr %a) nounwind { + %1 = load atomic i8, ptr %a seq_cst, align 1 + ret i8 %1 +; A6S: .attribute 14, 2 +; A6C: .attribute 14, 1 +} diff --git a/llvm/test/MC/RISCV/attribute.s b/llvm/test/MC/RISCV/attribute.s index 7685df46eb723..29a450071fccd 100644 --- a/llvm/test/MC/RISCV/attribute.s +++ b/llvm/test/MC/RISCV/attribute.s @@ -24,3 +24,6 @@ .attribute priv_spec_revision, 0 # CHECK: attribute 12, 0 + +.attribute atomic_abi, 0 +# CHECK: attribute 14, 0 diff --git a/llvm/test/MC/RISCV/invalid-attribute.s b/llvm/test/MC/RISCV/invalid-attribute.s index 2989e80b269ae..c640fccd15ae5 100644 --- a/llvm/test/MC/RISCV/invalid-attribute.s +++ b/llvm/test/MC/RISCV/invalid-attribute.s @@ -33,3 +33,6 @@ .attribute arch, 30 # CHECK: [[@LINE-1]]:18: error: expected string constant + +.attribute atomic_abi, "16" +# CHECK: [[@LINE-1]]:24: error: expected numeric constant From 5c57d12517ad58310511eb27bf7cc4ec660d4fa7 Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Tue, 2 Jul 2024 09:39:46 -0700 Subject: [PATCH 2/2] Add handling for invalid tags Created using spr 1.3.4 --- lld/ELF/Arch/RISCV.cpp | 22 ++++++++++++++++++++-- lld/test/ELF/riscv-attributes.s | 9 +++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index c48b9f7c11047..07a1b63be8051 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -1102,7 +1102,20 @@ static void mergeAtomic(DenseMap::iterator it, ": atomic_abi=" + Twine(static_cast(newTag))); }; - switch (static_cast(oldTag)) { + auto reportUnknownAbiError = [](const InputSectionBase *section, + RISCVAtomicAbiTag tag) { + switch (tag) { + case RISCVAtomicAbiTag::UNKNOWN: + case RISCVAtomicAbiTag::A6C: + case RISCVAtomicAbiTag::A6S: + case RISCVAtomicAbiTag::A7: + return; + }; + errorOrWarn("unknown atomic abi for " + section->name + "\n>>> " + + toString(section) + + ": atomic_abi=" + Twine(static_cast(tag))); + }; + switch (oldTag) { case RISCVAtomicAbiTag::UNKNOWN: it->getSecond() = static_cast(newTag); return; @@ -1145,7 +1158,12 @@ static void mergeAtomic(DenseMap::iterator it, return; }; }; - llvm_unreachable("unknown AtomicABI"); + + // If we get here, then we have an invalid tag, so report it. + // Putting these checks at the end allows us to only do these checks when we + // need to, since this is expected to be a rare occurrence. + reportUnknownAbiError(oldSection, oldTag); + reportUnknownAbiError(newSection, newTag); } static RISCVAttributesSection * diff --git a/lld/test/ELF/riscv-attributes.s b/lld/test/ELF/riscv-attributes.s index 38b0fe8e7797e..057223c18418e 100644 --- a/lld/test/ELF/riscv-attributes.s +++ b/lld/test/ELF/riscv-attributes.s @@ -52,6 +52,12 @@ # ATOMIC_ABI_ERROR-NEXT: >>> atomic_abi_A6C.o:(.riscv.attributes): atomic_abi=1 # ATOMIC_ABI_ERROR-NEXT: >>> atomic_abi_A7.o:(.riscv.attributes): atomic_abi=3 +## RISC-V tag merging for atomic_abi values A6C and invalid lead to an error. +# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_invalid.s -o atomic_abi_invalid.o +# RUN: not ld.lld atomic_abi_A6C.o atomic_abi_invalid.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ATOMIC_ABI_INVALID --implicit-check-not=error: +# ATOMIC_ABI_INVALID: error: unknown atomic abi for .riscv.attributes +# ATOMIC_ABI_INVALID-NEXT: >>> atomic_abi_invalid.o:(.riscv.attributes): atomic_abi=42 + # RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_A6S.s -o atomic_abi_A6S.o # RUN: ld.lld atomic_abi_A6S.o atomic_abi_A6C.o -o atomic_abi_A6C_A6S # RUN: llvm-readobj -A atomic_abi_A6C_A6S | FileCheck %s --check-prefix=A6C_A6S @@ -332,6 +338,9 @@ #--- atomic_abi_A7.s .attribute atomic_abi, 3 +#--- atomic_abi_invalid.s +.attribute atomic_abi, 42 + # UNKNOWN_NONE: BuildAttributes { # UNKNOWN_NONE-NEXT: FormatVersion: 0x41 # UNKNOWN_NONE-NEXT: Section 1 {