Skip to content

Commit

Permalink
[RFC][RISCV] Support RISC-V Profiles in -march option
Browse files Browse the repository at this point in the history
This PR implements the draft
riscv-non-isa/riscv-toolchain-conventions#36.

Currently, we replace specified profile in `-march` with standard
arch string.

We may need to pass it to backend so that we can emit an ELF attr
proposed by
riscv-non-isa/riscv-elf-psabi-doc#409.
  • Loading branch information
wangpc-pp committed Dec 28, 2023
1 parent 9d3fbf9 commit fa079e4
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 1 deletion.
112 changes: 112 additions & 0 deletions clang/test/Driver/riscv-profiles.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// RUN: %clang -### -c %s 2>&1 -march=rvi20u32 | FileCheck -check-prefix=RVI20U32 %s
// RVI20U32: "-target-cpu" "generic-rv32"
// RVI20U32: "-target-feature" "-a"
// RVI20U32: "-target-feature" "-c"
// RVI20U32: "-target-feature" "-d"
// RVI20U32: "-target-feature" "-f"
// RVI20U32: "-target-feature" "-m"
// RVI20U32: "-target-feature" "+rvi20u32"
// RVI20U32: "-target-abi" "ilp32"

// RUN: %clang -### -c %s 2>&1 -march=rvi20u64 | FileCheck -check-prefix=RVI20U64 %s
// RVI20U64: "-target-cpu" "generic-rv64"
// RVI20U64: "-target-feature" "-a"
// RVI20U64: "-target-feature" "-c"
// RVI20U64: "-target-feature" "-d"
// RVI20U64: "-target-feature" "-f"
// RVI20U64: "-target-feature" "-m"
// RVI20U64: "-target-feature" "+rvi20u64"
// RVI20U64: "-target-abi" "lp64"

// RUN: %clang -### -c %s 2>&1 -march=rva20u64 | FileCheck -check-prefix=RVA20U64 %s
// RVA20U64: "-target-cpu" "generic-rv64"
// RVA20U64: "-target-feature" "+m"
// RVA20U64: "-target-feature" "+a"
// RVA20U64: "-target-feature" "+f"
// RVA20U64: "-target-feature" "+d"
// RVA20U64: "-target-feature" "+c"
// RVA20U64: "-target-feature" "+zicsr"
// RVA20U64: "-target-feature" "+rva20u64"
// RVA20U64: "-target-abi" "lp64d"

// RUN: %clang -### -c %s 2>&1 -march=rva20s64 | FileCheck -check-prefix=RVA20S64 %s
// RVA20S64: "-target-cpu" "generic-rv64"
// RVA20S64: "-target-feature" "+m"
// RVA20S64: "-target-feature" "+a"
// RVA20S64: "-target-feature" "+f"
// RVA20S64: "-target-feature" "+d"
// RVA20S64: "-target-feature" "+c"
// RVA20S64: "-target-feature" "+zicsr"
// RVA20S64: "-target-feature" "+zifencei"
// RVA20S64: "-target-feature" "+rva20s64"
// RVA20S64: "-target-abi" "lp64d"

// RUN: %clang -### -c %s 2>&1 -march=rva22u64 | FileCheck -check-prefix=RVA22U64 %s
// RVA22U64: "-target-cpu" "generic-rv64"
// RVA22U64: "-target-feature" "+m"
// RVA22U64: "-target-feature" "+a"
// RVA22U64: "-target-feature" "+f"
// RVA22U64: "-target-feature" "+d"
// RVA22U64: "-target-feature" "+c"
// RVA22U64: "-target-feature" "+zicbom"
// RVA22U64: "-target-feature" "+zicbop"
// RVA22U64: "-target-feature" "+zicboz"
// RVA22U64: "-target-feature" "+zicsr"
// RVA22U64: "-target-feature" "+zihintpause"
// RVA22U64: "-target-feature" "+zfhmin"
// RVA22U64: "-target-feature" "+zba"
// RVA22U64: "-target-feature" "+zbb"
// RVA22U64: "-target-feature" "+zbs"
// RVA22U64: "-target-feature" "+zkt"
// RVA22U64: "-target-feature" "+rva22u64"
// RVA22U64: "-target-abi" "lp64d"

// RUN: %clang -### -c %s 2>&1 -march=rva22s64 | FileCheck -check-prefix=RVA22S64 %s
// RVA22S64: "-target-cpu" "generic-rv64"
// RVA22S64: "-target-feature" "+m"
// RVA22S64: "-target-feature" "+a"
// RVA22S64: "-target-feature" "+f"
// RVA22S64: "-target-feature" "+d"
// RVA22S64: "-target-feature" "+c"
// RVA22S64: "-target-feature" "+zicbom"
// RVA22S64: "-target-feature" "+zicbop"
// RVA22S64: "-target-feature" "+zicboz"
// RVA22S64: "-target-feature" "+zicsr"
// RVA22S64: "-target-feature" "+zifencei"
// RVA22S64: "-target-feature" "+zihintpause"
// RVA22S64: "-target-feature" "+zfhmin"
// RVA22S64: "-target-feature" "+zba"
// RVA22S64: "-target-feature" "+zbb"
// RVA22S64: "-target-feature" "+zbs"
// RVA22S64: "-target-feature" "+zkt"
// RVA22S64: "-target-feature" "+svinval"
// RVA22S64: "-target-feature" "+svpbmt"
// RVA22S64: "-target-feature" "+rva22s64"
// RVA22S64: "-target-abi" "lp64d"

// RUN: %clang -### -c %s 2>&1 -march=rva22u64_zfa | FileCheck -check-prefix=PROFILE-WITH-ADDITIONAL %s
// PROFILE-WITH-ADDITIONAL: "-target-cpu" "generic-rv64"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+m"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+a"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+f"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+d"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+c"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zicbom"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zicbop"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zicboz"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zicsr"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zihintpause"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zfa"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zfhmin"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zba"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zbb"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zbs"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zkt"
// PROFILE-WITH-ADDITIONAL: "-target-feature" "+rva22u64"
// PROFILE-WITH-ADDITIONAL: "-target-abi" "lp64d"

// RUN: not %clang -### -c %s 2>&1 -march=rva19u64_zfa | FileCheck -check-prefix=INVALID-PROFILE %s
// INVALID-PROFILE: error: invalid arch name 'rva19u64_zfa', unsupported profile

// RUN: not %clang -### -c %s 2>&1 -march=rva22u64zfa | FileCheck -check-prefix=INVALID-ADDITIONAL %s
// INVALID-ADDITIONAL: error: invalid arch name 'rva22u64zfa', additional extensions must be after separator '_'
4 changes: 3 additions & 1 deletion llvm/include/llvm/Support/RISCVISAInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class RISCVISAInfo {
unsigned getMaxVLen() const { return 65536; }
unsigned getMaxELen() const { return MaxELen; }
unsigned getMaxELenFp() const { return MaxELenFp; }
std::string getProfile() const { return Profile; }

bool hasExtension(StringRef Ext) const;
std::string toString() const;
Expand All @@ -97,12 +98,13 @@ class RISCVISAInfo {

private:
RISCVISAInfo(unsigned XLen)
: XLen(XLen), FLen(0), MinVLen(0), MaxELen(0), MaxELenFp(0) {}
: XLen(XLen), FLen(0), MinVLen(0), MaxELen(0), MaxELenFp(0), Profile() {}

unsigned XLen;
unsigned FLen;
unsigned MinVLen;
unsigned MaxELen, MaxELenFp;
std::string Profile;

OrderedExtensionMap Exts;

Expand Down
51 changes: 51 additions & 0 deletions llvm/lib/Support/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ struct RISCVSupportedExtension {
return StringRef(Name) < StringRef(RHS.Name);
}
};
struct RISCVProfile {
const char *Name;
const char *MArch;
};

} // end anonymous namespace

Expand Down Expand Up @@ -206,6 +210,17 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"zvfbfwma", RISCVExtensionVersion{0, 8}},
};

static const RISCVProfile SupportedProfiles[] = {
{"rvi20u32", "rv32i"},
{"rvi20u64", "rv64i"},
{"rva20u64", "rv64imafdc_zicsr"},
{"rva20s64", "rv64imafdc_zicsr_zifencei"},
{"rva22u64", "rv64imafdc_zicsr_zihintpause_zba_zbb_zbs_zicbom_zicbop_"
"zicboz_zfhmin_zkt"},
{"rva22s64", "rv64imafdc_zicsr_zifencei_zihintpause_zba_zbb_zbs_zicbom_"
"zicbop_zicboz_zfhmin_zkt_svpbmt_svinval"},
};

static void verifyTables() {
#ifndef NDEBUG
static std::atomic<bool> TableChecked(false);
Expand Down Expand Up @@ -494,6 +509,10 @@ void RISCVISAInfo::toFeatures(
Features.push_back(StrAlloc(Twine("-experimental-") + Ext.Name));
}
}

// Add profile feature.
if (!Profile.empty())
Features.push_back(StrAlloc(Twine("+") + Profile));
}

// Extensions may have a version number, and may be separated by
Expand Down Expand Up @@ -710,6 +729,36 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
"string must be lowercase");
}

bool IsProfile = Arch.starts_with("rvi") || Arch.starts_with("rva") ||
Arch.starts_with("rvb") || Arch.starts_with("rvm");
std::string NewArch;
std::string ProfileName;
if (IsProfile) {
const RISCVProfile *FoundProfile = nullptr;
for (const RISCVProfile &Profile : SupportedProfiles) {
if (Arch.starts_with(Profile.Name)) {
FoundProfile = &Profile;
break;
}
}

if (!FoundProfile)
return createStringError(errc::invalid_argument, "unsupported profile");

ProfileName = FoundProfile->Name;
NewArch = FoundProfile->MArch;

StringRef ArchWithoutProfile = Arch.substr(ProfileName.size());
if (!ArchWithoutProfile.empty()) {
if (!ArchWithoutProfile.starts_with("_"))
return createStringError(
errc::invalid_argument,
"additional extensions must be after separator '_'");
NewArch = NewArch + ArchWithoutProfile.str();
}
Arch = NewArch;
}

bool HasRV64 = Arch.starts_with("rv64");
// ISA string must begin with rv32 or rv64.
if (!(Arch.starts_with("rv32") || HasRV64) || (Arch.size() < 5)) {
Expand All @@ -720,6 +769,8 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,

unsigned XLen = HasRV64 ? 64 : 32;
std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
if (!ProfileName.empty())
ISAInfo->Profile = ProfileName;

// The canonical order specified in ISA manual.
// Ref: Table 22.1 in RISC-V User-Level ISA V2.2
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ include "RISCVSchedSyntacoreSCR1.td"

include "RISCVProcessors.td"

//===----------------------------------------------------------------------===//
// RISC-V profiles supported.
//===----------------------------------------------------------------------===//

include "RISCVProfiles.td"

//===----------------------------------------------------------------------===//
// Define the RISC-V target.
//===----------------------------------------------------------------------===//
Expand Down
70 changes: 70 additions & 0 deletions llvm/lib/Target/RISCV/RISCVProfiles.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//===------ RISCVProfiles.td - RISC-V Profiles -------------*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

class RISCVProfile<string name, list<SubtargetFeature> features>
: SubtargetFeature<name, "RISCVProfile", NAME,
"RISC-V " # name # " profile",
features>;

def RVI20U32 : RISCVProfile<"rvi20u32", [Feature32Bit]>;

def RVI20U64 : RISCVProfile<"rvi20u64", [Feature64Bit]>;

def RVA20U64 : RISCVProfile<"rva20u64", [Feature64Bit,
FeatureStdExtM,
FeatureStdExtA,
FeatureStdExtF,
FeatureStdExtD,
FeatureStdExtC,
FeatureStdExtZicsr]>;

def RVA20S64 : RISCVProfile<"rva20s64", [Feature64Bit,
FeatureStdExtM,
FeatureStdExtA,
FeatureStdExtF,
FeatureStdExtD,
FeatureStdExtC,
FeatureStdExtZicsr,
FeatureStdExtZifencei]>;

def RVA22U64 : RISCVProfile<"rva22u64", [Feature64Bit,
FeatureStdExtM,
FeatureStdExtA,
FeatureStdExtF,
FeatureStdExtD,
FeatureStdExtC,
FeatureStdExtZba,
FeatureStdExtZbb,
FeatureStdExtZbs,
FeatureStdExtZfhmin,
FeatureStdExtZicbom,
FeatureStdExtZicbop,
FeatureStdExtZicboz,
FeatureStdExtZkt,
FeatureStdExtZicsr,
FeatureStdExtZihintpause]>;

def RVA22S64 : RISCVProfile<"rva22s64", [Feature64Bit,
FeatureStdExtM,
FeatureStdExtA,
FeatureStdExtF,
FeatureStdExtD,
FeatureStdExtC,
FeatureStdExtZba,
FeatureStdExtZbb,
FeatureStdExtZbs,
FeatureStdExtZfhmin,
FeatureStdExtZicbom,
FeatureStdExtZicbop,
FeatureStdExtZicboz,
FeatureStdExtZkt,
FeatureStdExtZicsr,
FeatureStdExtZifencei,
FeatureStdExtZihintpause,
FeatureStdExtSvpbmt,
FeatureStdExtSvinval]>;
14 changes: 14 additions & 0 deletions llvm/lib/Target/RISCV/RISCVSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ struct RISCVTuneInfo {
#include "RISCVGenSearchableTables.inc"
} // namespace RISCVTuneInfoTable

enum RISCVProfileEnum : uint8_t {
Unspecified,
RVA20S64,
RVA20U64,
RVA22S64,
RVA22U64,
RVI20U32,
RVI20U64,
};

class RISCVSubtarget : public RISCVGenSubtargetInfo {
public:
// clang-format off
Expand All @@ -67,6 +77,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {

RISCVProcFamilyEnum RISCVProcFamily = Others;

RISCVProfileEnum RISCVProfile = Unspecified;

#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
bool ATTRIBUTE = DEFAULT;
#include "RISCVGenSubtargetInfo.inc"
Expand Down Expand Up @@ -135,6 +147,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
/// initializeProperties().
RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }

RISCVProfileEnum getRISCVProfile() const { return RISCVProfile; }

#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
bool GETTER() const { return ATTRIBUTE; }
#include "RISCVGenSubtargetInfo.inc"
Expand Down
15 changes: 15 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV64ZICFILP %s

; Tests for profile features.
; RUN: llc -mtriple=riscv32 -mattr=+rvi20u32 %s -o - | FileCheck --check-prefix=RVI20U32 %s
; RUN: llc -mtriple=riscv64 -mattr=+rvi20u64 %s -o - | FileCheck --check-prefix=RVI20U64 %s
; RUN: llc -mtriple=riscv64 -mattr=+rva20u64 %s -o - | FileCheck --check-prefix=RVA20U64 %s
; RUN: llc -mtriple=riscv64 -mattr=+rva20s64 %s -o - | FileCheck --check-prefix=RVA20S64 %s
; RUN: llc -mtriple=riscv64 -mattr=+rva22u64 %s -o - | FileCheck --check-prefix=RVA22U64 %s
; RUN: llc -mtriple=riscv64 -mattr=+rva22s64 %s -o - | FileCheck --check-prefix=RVA22S64 %s

; CHECK: .attribute 4, 16

; RV32M: .attribute 5, "rv32i2p1_m2p0"
Expand Down Expand Up @@ -378,6 +386,13 @@
; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0"
; RV64ZICFILP: .attribute 5, "rv64i2p1_zicfilp0p4"

; RVI20U32: .attribute 5, "rv32i2p1"
; RVI20U64: .attribute 5, "rv64i2p1"
; RVA20U64: .attribute 5, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0"
; RVA20S64: .attribute 5, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0"
; RVA22U64: .attribute 5, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicbom1p0_zicbop1p0_zicboz1p0_zicsr2p0_zihintpause2p0_zfhmin1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0"
; RVA22S64: .attribute 5, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicbom1p0_zicbop1p0_zicboz1p0_zicsr2p0_zifencei2p0_zihintpause2p0_zfhmin1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_svinval1p0_svpbmt1p0"

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

0 comments on commit fa079e4

Please sign in to comment.