350 changes: 175 additions & 175 deletions clang/test/CodeGen/RISCV/ntlh-intrinsics/riscv32-zihintntl.c

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions clang/test/CodeGen/RISCV/riscv-metadata-arch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 -triple riscv32 -emit-llvm -o - %s \
// RUN: | FileCheck -check-prefix=RV32I %s
// RUN: %clang_cc1 -triple riscv32 -target-feature +v -emit-llvm -o - %s \
// RUN: | FileCheck -check-prefix=RV32IV %s
// RUN: %clang_cc1 -triple riscv64 -emit-llvm -o - %s \
// RUN: | FileCheck -check-prefix=RV64I %s
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -emit-llvm -o - %s \
// RUN: | FileCheck -check-prefix=RV64IV %s

// RV32I:!{{[0-9]+}} = !{i32 6, !"riscv-isa", ![[ID:[0-9]+]]}
// RV32I:![[ID]] = !{!"rv32i2p1"}

// RV32IV:!{{[0-9]+}} = !{i32 6, !"riscv-isa", ![[ID:[0-9]+]]}
// RV32IV:![[ID]] = !{!"rv32i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"}

// RV64I:!{{[0-9]+}} = !{i32 6, !"riscv-isa", ![[ID:[0-9]+]]}
// RV64I:![[ID]] = !{!"rv64i2p1"}

// RV64IV:!{{[0-9]+}} = !{i32 6, !"riscv-isa", ![[ID:[0-9]+]]}
// RV64IV:![[ID]] = !{!"rv64i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"}
8 changes: 4 additions & 4 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ using namespace llvm;
// This part is for ELF object output.
RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
const MCSubtargetInfo &STI)
: RISCVTargetStreamer(S), CurrentVendor("riscv"), STI(STI) {
: RISCVTargetStreamer(S), CurrentVendor("riscv") {
MCAssembler &MCA = getStreamer().getAssembler();
const FeatureBitset &Features = STI.getFeatureBits();
auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features,
MAB.getTargetOptions().getABIName()));
setFlagsFromFeatures(STI);
// `j label` in `.option norelax; j label; .option relax; ...; label:` needs a
// relocation to ensure the jump target is correct after linking. This is due
// to a limitation that shouldForceRelocation has to make the decision upfront
Expand Down Expand Up @@ -87,14 +88,13 @@ void RISCVTargetELFStreamer::finishAttributeSection() {
void RISCVTargetELFStreamer::finish() {
RISCVTargetStreamer::finish();
MCAssembler &MCA = getStreamer().getAssembler();
const FeatureBitset &Features = STI.getFeatureBits();
RISCVABI::ABI ABI = getTargetABI();

unsigned EFlags = MCA.getELFHeaderEFlags();

if (Features[RISCV::FeatureStdExtC])
if (hasRVC())
EFlags |= ELF::EF_RISCV_RVC;
if (Features[RISCV::FeatureStdExtZtso])
if (hasTSO())
EFlags |= ELF::EF_RISCV_TSO;

switch (ABI) {
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer {
StringRef CurrentVendor;

MCSection *AttributeSection = nullptr;
const MCSubtargetInfo &STI;

void emitAttribute(unsigned Attribute, unsigned Value) override;
void emitTextAttribute(unsigned Attribute, StringRef String) override;
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ void RISCVTargetStreamer::setTargetABI(RISCVABI::ABI ABI) {
TargetABI = ABI;
}

void RISCVTargetStreamer::setFlagsFromFeatures(const MCSubtargetInfo &STI) {
HasRVC = STI.hasFeature(RISCV::FeatureStdExtC);
HasTSO = STI.hasFeature(RISCV::FeatureStdExtZtso);
}

void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI,
bool EmitStackAlign) {
if (EmitStackAlign) {
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ struct RISCVOptionArchArg {

class RISCVTargetStreamer : public MCTargetStreamer {
RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
bool HasRVC = false;
bool HasTSO = false;

public:
RISCVTargetStreamer(MCStreamer &S);
Expand All @@ -58,6 +60,9 @@ class RISCVTargetStreamer : public MCTargetStreamer {
void emitTargetAttributes(const MCSubtargetInfo &STI, bool EmitStackAlign);
void setTargetABI(RISCVABI::ABI ABI);
RISCVABI::ABI getTargetABI() const { return TargetABI; }
void setFlagsFromFeatures(const MCSubtargetInfo &STI);
bool hasRVC() const { return HasRVC; }
bool hasTSO() const { return HasTSO; }
};

// This part is for ascii assembly output
Expand Down
32 changes: 28 additions & 4 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class RISCVAsmPrinter : public AsmPrinter {
bool emitDirectiveOptionArch();

private:
void emitAttributes();
void emitAttributes(const MCSubtargetInfo &SubtargetInfo);

void emitNTLHint(const MachineInstr *MI);

Expand Down Expand Up @@ -385,8 +385,32 @@ void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) {
if (const MDString *ModuleTargetABI =
dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi")))
RTS.setTargetABI(RISCVABI::getTargetABI(ModuleTargetABI->getString()));

MCSubtargetInfo SubtargetInfo = *TM.getMCSubtargetInfo();

// Use module flag to update feature bits.
if (auto *MD = dyn_cast_or_null<MDNode>(M.getModuleFlag("riscv-isa"))) {
for (auto &ISA : MD->operands()) {
if (auto *ISAString = dyn_cast_or_null<MDString>(ISA)) {
auto ParseResult = llvm::RISCVISAInfo::parseArchString(
ISAString->getString(), /*EnableExperimentalExtension=*/true,
/*ExperimentalExtensionVersionCheck=*/true);
if (!errorToBool(ParseResult.takeError())) {
auto &ISAInfo = *ParseResult;
for (const auto &Feature : RISCVFeatureKV) {
if (ISAInfo->hasExtension(Feature.Key) &&
!SubtargetInfo.hasFeature(Feature.Value))
SubtargetInfo.ToggleFeature(Feature.Key);
}
}
}
}

RTS.setFlagsFromFeatures(SubtargetInfo);
}

if (TM.getTargetTriple().isOSBinFormatELF())
emitAttributes();
emitAttributes(SubtargetInfo);
}

void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
Expand All @@ -398,13 +422,13 @@ void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
EmitHwasanMemaccessSymbols(M);
}

void RISCVAsmPrinter::emitAttributes() {
void RISCVAsmPrinter::emitAttributes(const MCSubtargetInfo &SubtargetInfo) {
RISCVTargetStreamer &RTS =
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
// Use MCSubtargetInfo from TargetMachine. Individual functions may have
// attributes that differ from other functions in the module and we have no
// way to know which function is correct.
RTS.emitTargetAttributes(*TM.getMCSubtargetInfo(), /*EmitStackAlign*/ true);
RTS.emitTargetAttributes(SubtargetInfo, /*EmitStackAlign*/ true);
}

void RISCVAsmPrinter::emitFunctionEntryLabel() {
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes-module-flag.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; RUN: llc -mtriple=riscv32 %s -o - | FileCheck %s --check-prefix=RV32
; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s --check-prefix=RV64

; Test generation of ELF attribute from module metadata

; RV32: .attribute 5, "rv32i2p1_m2p0_zba1p0"
; RV64: .attribute 5, "rv64i2p1_m2p0_zba1p0"

define i32 @addi(i32 %a) {
%1 = add i32 %a, 1
ret i32 %1
}

!llvm.module.flags = !{!0}

!0 = !{i32 6, !"riscv-isa", !1}
!1 = !{!"rv64i2p1_m2p0", !"rv64i2p1_zba1p0"}
13 changes: 13 additions & 0 deletions llvm/test/CodeGen/RISCV/module-elf-flags.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s

; FLAGS: Flags: 0x11, RVC, TSO

define i32 @addi(i32 %a) {
%1 = add i32 %a, 1
ret i32 %1
}

!llvm.module.flags = !{!0}

!0 = !{i32 6, !"riscv-isa", !1}
!1 = !{!"rv64i2p1_c2p0_ztso0p1"}