Skip to content

[RISCV] Support RISCV Atomics ABI attributes #84597

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

Merged
Merged
63 changes: 63 additions & 0 deletions lld/ELF/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1084,10 +1084,62 @@ static void mergeArch(RISCVISAInfo::OrderedExtensionMap &mergedExts,
}
}

static void mergeAtomic(DenseMap<unsigned, unsigned>::iterator it,
const InputSectionBase *oldSection,
const InputSectionBase *newSection, unsigned int oldTag,
unsigned int newTag) {
using RISCVAttrs::RISCVAtomicAbiTag::AtomicABI;
// Same tags stay the same, and UNKNOWN is compatible with anything
if (oldTag == newTag || newTag == AtomicABI::UNKNOWN)
return;

switch (oldTag) {
case AtomicABI::UNKNOWN:
it->getSecond() = newTag;
return;
case AtomicABI::A6C:
switch (newTag) {
case AtomicABI::A6S:
it->getSecond() = AtomicABI::A6C;
return;
case AtomicABI::A7:
errorOrWarn(toString(oldSection) + " has atomic_abi=" + Twine(oldTag) +
" but " + toString(newSection) +
" has atomic_abi=" + Twine(newTag));
return;
};

case AtomicABI::A6S:
switch (newTag) {
case AtomicABI::A6C:
it->getSecond() = AtomicABI::A6C;
return;
case AtomicABI::A7:
it->getSecond() = AtomicABI::A7;
return;
};

case AtomicABI::A7:
switch (newTag) {
case AtomicABI::A6S:
it->getSecond() = AtomicABI::A7;
return;
case AtomicABI::A6C:
errorOrWarn(toString(oldSection) + " has atomic_abi=" + Twine(oldTag) +
" but " + toString(newSection) +
" has atomic_abi=" + Twine(newTag));
return;
};
default:
llvm_unreachable("unknown AtomicABI");
};
}

static RISCVAttributesSection *
mergeAttributesSection(const SmallVector<InputSectionBase *, 0> &sections) {
RISCVISAInfo::OrderedExtensionMap exts;
const InputSectionBase *firstStackAlign = nullptr;
const InputSectionBase *firstAtomicAbi = nullptr;
unsigned firstStackAlignValue = 0, xlen = 0;
bool hasArch = false;

Expand Down Expand Up @@ -1134,6 +1186,17 @@ mergeAttributesSection(const SmallVector<InputSectionBase *, 0> &sections) {
case RISCVAttrs::PRIV_SPEC_MINOR:
case RISCVAttrs::PRIV_SPEC_REVISION:
break;

case llvm::RISCVAttrs::AttrType::ATOMIC_ABI:
if (auto i = parser.getAttributeValue(tag.attr)) {
auto r = merged.intAttr.try_emplace(tag.attr, *i);
if (r.second) {
firstAtomicAbi = sec;
} else {
mergeAtomic(r.first, firstAtomicAbi, sec, r.first->getSecond(), *i);
}
}
continue;
}

// Fallback for deprecated priv_spec* and other unknown attributes: retain
Expand Down
126 changes: 126 additions & 0 deletions lld/test/ELF/riscv-attributes.s
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,30 @@
# RUN: not ld.lld a.o b.o c.o diff_stack_align.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=STACK_ALIGN --implicit-check-not=error:
# STACK_ALIGN: error: diff_stack_align.o:(.riscv.attributes) has stack_align=32 but a.o:(.riscv.attributes) has stack_align=16

## merging atomic_abi values for A6C and A7 lead to an error.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mismatched

Upper case. And there is a better word than "merging"

# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_A6C.s -o atomic_abi_A6C.o
# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_A7.s -o atomic_abi_A7.o
# RUN: not ld.lld atomic_abi_A6C.o atomic_abi_A7.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ATOMIC_ABI_ERROR --implicit-check-not=error:
# ATOMIC_ABI_ERROR: error: atomic_abi_A6C.o:(.riscv.attributes) has atomic_abi=1 but atomic_abi_A7.o:(.riscv.attributes) has atomic_abi=3

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use double blank lines


# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_A6S.s -o atomic_abi_A6S.o
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excess space

# 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

# RUN: ld.lld atomic_abi_A6S.o atomic_abi_A7.o -o atomic_abi_A6S_A7
# RUN: llvm-readobj -A atomic_abi_A6S_A7 | FileCheck %s --check-prefix=A6S_A7

# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_unknown.s -o atomic_abi_unknown.o
# RUN: ld.lld atomic_abi_unknown.o atomic_abi_A6C.o -o atomic_abi_A6C_unknown
# RUN: llvm-readobj -A atomic_abi_A6C_unknown | FileCheck %s --check-prefixes=UNKNOWN_A6C

# RUN: ld.lld atomic_abi_unknown.o atomic_abi_A6S.o -o atomic_abi_A6S_unknown
# RUN: llvm-readobj -A atomic_abi_A6S_unknown | FileCheck %s --check-prefix=UNKNOWN_A6S

# RUN: ld.lld atomic_abi_unknown.o atomic_abi_A7.o -o atomic_abi_A7_unknown
# RUN: llvm-readobj -A atomic_abi_A7_unknown | FileCheck %s --check-prefix=UNKNOWN_A7

## The deprecated priv_spec is not handled as GNU ld does.
## Differing priv_spec attributes lead to an absent attribute.
# RUN: llvm-mc -filetype=obj -triple=riscv64 diff_priv_spec.s -o diff_priv_spec.o
Expand Down Expand Up @@ -286,6 +310,108 @@
.attribute priv_spec, 3
.attribute priv_spec_minor, 3

#--- atomic_abi_unknown.s
.attribute atomic_abi, 0

#--- atomic_abi_A6C.s
.attribute atomic_abi, 1

#--- atomic_abi_A6S.s
.attribute atomic_abi, 2

#--- atomic_abi_A7.s
.attribute atomic_abi, 3

# UNKNOWN_A6C: BuildAttributes {
# UNKNOWN_A6C-NEXT: FormatVersion: 0x41
# UNKNOWN_A6C-NEXT: Section 1 {
# UNKNOWN_A6C-NEXT: SectionLength: 17
# UNKNOWN_A6C-NEXT: Vendor: riscv
# UNKNOWN_A6C-NEXT: Tag: Tag_File (0x1)
# UNKNOWN_A6C-NEXT: Size: 7
# UNKNOWN_A6C-NEXT: FileAttributes {
# UNKNOWN_A6C-NEXT: Attribute {
# UNKNOWN_A6C-NEXT: Tag: 14
# UNKNOWN_A6C-NEXT: Value: 1
# UNKNOWN_A6C-NEXT: TagName: atomic_abi
# UNKNOWN_A6C-NEXT: Description: Atomic ABI is 1
# UNKNOWN_A6C-NEXT: }
# UNKNOWN_A6C-NEXT: }
# UNKNOWN_A6C-NEXT: }
# UNKNOWN_A6C-NEXT: }

# UNKNOWN_A6S: BuildAttributes {
# UNKNOWN_A6S-NEXT: FormatVersion: 0x41
# UNKNOWN_A6S-NEXT: Section 1 {
# UNKNOWN_A6S-NEXT: SectionLength: 17
# UNKNOWN_A6S-NEXT: Vendor: riscv
# UNKNOWN_A6S-NEXT: Tag: Tag_File (0x1)
# UNKNOWN_A6S-NEXT: Size: 7
# UNKNOWN_A6S-NEXT: FileAttributes {
# UNKNOWN_A6S-NEXT: Attribute {
# UNKNOWN_A6S-NEXT: Tag: 14
# UNKNOWN_A6S-NEXT: Value: 2
# UNKNOWN_A6S-NEXT: TagName: atomic_abi
# UNKNOWN_A6S-NEXT: Description: Atomic ABI is 2
# UNKNOWN_A6S-NEXT: }
# UNKNOWN_A6S-NEXT: }
# UNKNOWN_A6S-NEXT: }
# UNKNOWN_A6S-NEXT: }

# UNKNOWN_A7: BuildAttributes {
# UNKNOWN_A7-NEXT: FormatVersion: 0x41
# UNKNOWN_A7-NEXT: Section 1 {
# UNKNOWN_A7-NEXT: SectionLength: 17
# UNKNOWN_A7-NEXT: Vendor: riscv
# UNKNOWN_A7-NEXT: Tag: Tag_File (0x1)
# UNKNOWN_A7-NEXT: Size: 7
# UNKNOWN_A7-NEXT: FileAttributes {
# UNKNOWN_A7-NEXT: Attribute {
# UNKNOWN_A7-NEXT: Tag: 14
# UNKNOWN_A7-NEXT: Value: 3
# UNKNOWN_A7-NEXT: TagName: atomic_abi
# UNKNOWN_A7-NEXT: Description: Atomic ABI is 3
# UNKNOWN_A7-NEXT: }
# UNKNOWN_A7-NEXT: }
# UNKNOWN_A7-NEXT: }
# UNKNOWN_A7-NEXT: }

# A6C_A6S: BuildAttributes {
# A6C_A6S-NEXT: FormatVersion: 0x41
# A6C_A6S-NEXT: Section 1 {
# A6C_A6S-NEXT: SectionLength: 17
# A6C_A6S-NEXT: Vendor: riscv
# A6C_A6S-NEXT: Tag: Tag_File (0x1)
# A6C_A6S-NEXT: Size: 7
# A6C_A6S-NEXT: FileAttributes {
# A6C_A6S-NEXT: Attribute {
# A6C_A6S-NEXT: Tag: 14
# A6C_A6S-NEXT: Value: 1
# A6C_A6S-NEXT: TagName: atomic_abi
# A6C_A6S-NEXT: Description: Atomic ABI is 1
# A6C_A6S-NEXT: }
# A6C_A6S-NEXT: }
# A6C_A6S-NEXT: }
# A6C_A6S-NEXT: }

# A6S_A7: BuildAttributes {
# A6S_A7-NEXT: FormatVersion: 0x41
# A6S_A7-NEXT: Section 1 {
# A6S_A7-NEXT: SectionLength: 17
# A6S_A7-NEXT: Vendor: riscv
# A6S_A7-NEXT: Tag: Tag_File (0x1)
# A6S_A7-NEXT: Size: 7
# A6S_A7-NEXT: FileAttributes {
# A6S_A7-NEXT: Attribute {
# A6S_A7-NEXT: Tag: 14
# A6S_A7-NEXT: Value: 3
# A6S_A7-NEXT: TagName: atomic_abi
# A6S_A7-NEXT: Description: Atomic ABI is 3
# A6S_A7-NEXT: }
# A6S_A7-NEXT: }
# A6S_A7-NEXT: }
# A6S_A7-NEXT: }

#--- unknown13.s
.attribute 13, "0"
#--- unknown13a.s
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/RISCVAttributeParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class RISCVAttributeParser : public ELFAttributeParser {

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

public:
RISCVAttributeParser(ScopedPrinter *sw)
Expand Down
13 changes: 13 additions & 0 deletions llvm/include/llvm/Support/RISCVAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,21 @@ enum AttrType : unsigned {
PRIV_SPEC = 8,
PRIV_SPEC_MINOR = 10,
PRIV_SPEC_REVISION = 12,
ATOMIC_ABI = 14,
};

namespace RISCVAtomicAbiTag {
enum AtomicABI : 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,
};
} // namespace RISCVAtomicAbiTag

enum { NOT_ALLOWED = 0, ALLOWED = 1 };

} // namespace RISCVAttrs
Expand Down
13 changes: 12 additions & 1 deletion llvm/lib/Support/RISCVAttributeParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"};
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Support/RISCVAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI,
auto &ISAInfo = *ParseResult;
emitTextAttribute(RISCVAttrs::ARCH, ISAInfo->toString());
}

if (STI.hasFeature(RISCV::FeatureStdExtA)) {
unsigned AtomicABITag = STI.hasFeature(RISCV::FeatureTrailingSeqCstFence)
? RISCVAttrs::RISCVAtomicAbiTag::AtomicABI::A6S
: RISCVAttrs::RISCVAtomicAbiTag::AtomicABI::A6C;
emitAttribute(RISCVAttrs::ATOMIC_ABI, AtomicABITag);
}
}

// This part is for ascii assembly output
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -1178,10 +1178,10 @@ foreach i = {1-31} in
def FeatureSaveRestore : SubtargetFeature<"save-restore", "EnableSaveRestore",
"true", "Enable save/restore.">;

def FeatureTrailingSeqCstFence : SubtargetFeature<"seq-cst-trailing-fence",
def FeatureTrailingSeqCstFence : SubtargetFeature<"no-seq-cst-trailing-fence",
"EnableSeqCstTrailingFence",
"true",
"Enable trailing fence for seq-cst store.">;
"false",
"Disable trailing fence for seq-cst store.">;

def FeatureFastUnalignedAccess
: SubtargetFeature<"fast-unaligned-access", "HasFastUnalignedAccess",
Expand Down
16 changes: 8 additions & 8 deletions llvm/test/CodeGen/RISCV/atomic-load-store.ll
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I %s
; RUN: llc -mtriple=riscv32 -mattr=+a -verify-machineinstrs < %s \
; RUN: llc -mtriple=riscv32 -mattr=+a,+no-seq-cst-trailing-fence -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV32IA,RV32IA-WMO %s
; RUN: llc -mtriple=riscv32 -mattr=+a,+experimental-ztso -verify-machineinstrs < %s \
; RUN: llc -mtriple=riscv32 -mattr=+a,+no-seq-cst-trailing-fence,+experimental-ztso -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV32IA,RV32IA-TSO %s
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV64I %s
; RUN: llc -mtriple=riscv64 -mattr=+a -verify-machineinstrs < %s \
; RUN: llc -mtriple=riscv64 -mattr=+a,+no-seq-cst-trailing-fence -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-WMO %s
; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso -verify-machineinstrs < %s \
; RUN: llc -mtriple=riscv64 -mattr=+a,+no-seq-cst-trailing-fence,+experimental-ztso -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-TSO %s


; RUN: llc -mtriple=riscv32 -mattr=+a,+seq-cst-trailing-fence -verify-machineinstrs < %s \
; RUN: llc -mtriple=riscv32 -mattr=+a -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV32IA,RV32IA-WMO-TRAILING-FENCE %s
; RUN: llc -mtriple=riscv32 -mattr=+a,+experimental-ztso,+seq-cst-trailing-fence -verify-machineinstrs < %s \
; RUN: llc -mtriple=riscv32 -mattr=+a,+experimental-ztso -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV32IA,RV32IA-TSO-TRAILING-FENCE %s

; RUN: llc -mtriple=riscv64 -mattr=+a,+seq-cst-trailing-fence -verify-machineinstrs < %s \
; RUN: llc -mtriple=riscv64 -mattr=+a -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-WMO-TRAILING-FENCE %s
; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+seq-cst-trailing-fence -verify-machineinstrs < %s \
; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-TSO-TRAILING-FENCE %s


Expand Down
10 changes: 9 additions & 1 deletion llvm/test/CodeGen/RISCV/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,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 %s -o - | FileCheck --check-prefixes=CHECK,RV64A,A6C %s
; RUN: llc -mtriple=riscv64 -mattr=+a,+no-seq-cst-trailing-fence %s -o - | FileCheck --check-prefixes=CHECK,RV64A,A6S %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
; RUN: llc -mtriple=riscv64 -mattr=+c %s -o - | FileCheck --check-prefixes=CHECK,RV64C %s
Expand Down Expand Up @@ -512,3 +513,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
}
12 changes: 6 additions & 6 deletions llvm/test/CodeGen/RISCV/forced-atomics.ll
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+seq-cst-trailing-fence < %s | FileCheck %s --check-prefixes=RV32,RV32-NO-ATOMIC
; RUN: llc -mtriple=riscv32 -mattr=+no-seq-cst-trailing-fence < %s | FileCheck %s --check-prefixes=RV32,RV32-NO-ATOMIC
; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=RV32,RV32-NO-ATOMIC
; RUN: llc -mtriple=riscv32 -mattr=+forced-atomics < %s | FileCheck %s --check-prefixes=RV32,RV32-ATOMIC
; RUN: llc -mtriple=riscv32 -mattr=+forced-atomics,+seq-cst-trailing-fence < %s | FileCheck %s --check-prefixes=RV32,RV32-ATOMIC-TRAILING
; RUN: llc -mtriple=riscv32 -mattr=+forced-atomics,+no-seq-cst-trailing-fence < %s | FileCheck %s --check-prefixes=RV32,RV32-ATOMIC
; RUN: llc -mtriple=riscv32 -mattr=+forced-atomics < %s | FileCheck %s --check-prefixes=RV32,RV32-ATOMIC-TRAILING
; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=RV64,RV64-NO-ATOMIC
; RUN: llc -mtriple=riscv64 -mattr=+seq-cst-trailing-fence < %s | FileCheck %s --check-prefixes=RV64,RV64-NO-ATOMIC
; RUN: llc -mtriple=riscv64 -mattr=+forced-atomics < %s | FileCheck %s --check-prefixes=RV64,RV64-ATOMIC
; RUN: llc -mtriple=riscv64 -mattr=+forced-atomics,+seq-cst-trailing-fence < %s | FileCheck %s --check-prefixes=RV64,RV64-ATOMIC-TRAILING
; RUN: llc -mtriple=riscv64 -mattr=+no-seq-cst-trailing-fence < %s | FileCheck %s --check-prefixes=RV64,RV64-NO-ATOMIC
; RUN: llc -mtriple=riscv64 -mattr=+forced-atomics,+no-seq-cst-trailing-fence < %s | FileCheck %s --check-prefixes=RV64,RV64-ATOMIC
; RUN: llc -mtriple=riscv64 -mattr=+forced-atomics < %s | FileCheck %s --check-prefixes=RV64,RV64-ATOMIC-TRAILING

define i8 @load8(ptr %p) nounwind {
; RV32-NO-ATOMIC-LABEL: load8:
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/RISCV/attribute.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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