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

This patch adds support for the atomic_abi attribute, specifid in
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#tag_riscv_atomic_abi-14-uleb128version.

This was previously reverted due to ld.bfd segfaulting w/ unknown riscv
attributes. Attribute emission is now guarded by a backend flag
`--riscv-abi-attributes`, which is off by default. Linker support in
LLD for attribute merging is now in a standalone patch.

Reviewers: kito-cheng, MaskRay, asb

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/90266
This commit is contained in:
Paul Kirth 2024-07-02 08:23:03 -07:00 committed by GitHub
parent cfbad45339
commit b146a57f67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 60 additions and 2 deletions

View File

@ -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

View File

@ -24,6 +24,7 @@ class RISCVAttributeParser : public ELFAttributeParser {
Error unalignedAccess(unsigned tag);
Error stackAlign(unsigned tag);
Error atomicAbi(unsigned tag);
public:
RISCVAttributeParser(ScopedPrinter *sw)

View File

@ -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 };

View File

@ -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"};

View File

@ -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};

View File

@ -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

View File

@ -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
}

View File

@ -24,3 +24,6 @@
.attribute priv_spec_revision, 0
# CHECK: attribute 12, 0
.attribute atomic_abi, 0
# CHECK: attribute 14, 0

View File

@ -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