Skip to content

Reapply "[RISCV] Support RISCV Atomics ABI attributes (#84597)" #90266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4 changes: 4 additions & 0 deletions lld/ELF/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
@@ -1134,6 +1134,10 @@ mergeAttributesSection(const SmallVector<InputSectionBase *, 0> &sections) {
case RISCVAttrs::PRIV_SPEC_MINOR:
case RISCVAttrs::PRIV_SPEC_REVISION:
break;

case RISCVAttrs::AttrType::ATOMIC_ABI:
// TODO: Handle ATOMIC_ABI tag merging
continue;
}

// Fallback for deprecated priv_spec* and other unknown attributes: retain
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/RISCVAttributeParser.h
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ class RISCVAttributeParser : public ELFAttributeParser {

Error unalignedAccess(unsigned tag);
Error stackAlign(unsigned tag);
Error atomicAbi(unsigned tag);

public:
RISCVAttributeParser(ScopedPrinter *sw)
11 changes: 11 additions & 0 deletions llvm/include/llvm/Support/RISCVAttributes.h
Original file line number Diff line number Diff line change
@@ -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 };
13 changes: 12 additions & 1 deletion llvm/lib/Support/RISCVAttributeParser.cpp
Original file line number Diff line number Diff line change
@@ -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"};
1 change: 1 addition & 0 deletions llvm/lib/Support/RISCVAttributes.cpp
Original file line number Diff line number Diff line change
@@ -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};
16 changes: 16 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
Original file line number Diff line number Diff line change
@@ -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<bool> RiscvAbiAttr(
"riscv-abi-attributes",
cl::desc("Enable emitting RISC-V ELF attributes for ABI features"),
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<unsigned>(STI.hasFeature(RISCV::FeatureTrailingSeqCstFence)
? RISCVAttrs::RISCVAtomicAbiTag::A6S
: RISCVAttrs::RISCVAtomicAbiTag::A6C);
emitAttribute(RISCVAttrs::ATOMIC_ABI, AtomicABITag);
}
}

// This part is for ascii assembly output
10 changes: 9 additions & 1 deletion llvm/test/CodeGen/RISCV/attributes.ll
Original file line number Diff line number Diff line change
@@ -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
}
3 changes: 3 additions & 0 deletions llvm/test/MC/RISCV/attribute.s
Original file line number Diff line number Diff line change
@@ -24,3 +24,6 @@

.attribute priv_spec_revision, 0
# CHECK: attribute 12, 0

.attribute atomic_abi, 0
# CHECK: attribute 14, 0
3 changes: 3 additions & 0 deletions llvm/test/MC/RISCV/invalid-attribute.s
Original file line number Diff line number Diff line change
@@ -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