Skip to content

Commit

Permalink
merge main into amd-stg-open
Browse files Browse the repository at this point in the history
Change-Id: If5684cdce3bd26d978424346a19539bb9add5151
  • Loading branch information
Jenkins committed Nov 24, 2023
2 parents 0b9d089 + 579e721 commit 6e10f49
Show file tree
Hide file tree
Showing 34 changed files with 3,298 additions and 2,578 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -3177,6 +3177,10 @@ def warn_unsupported_target_attribute
def err_attribute_unsupported
: Error<"%0 attribute is not supported on targets missing %1;"
" specify an appropriate -march= or -mcpu=">;
def err_duplicate_target_attribute
: Error<"%select{unsupported|duplicate|unknown}0%select{| CPU|"
" tune CPU}1 '%2' in the '%select{target|target_clones|target_version}3' "
"attribute string; ">;
// The err_*_attribute_argument_not_int are separate because they're used by
// VerifyIntegerConstantExpression.
def err_aligned_attribute_argument_not_int : Error<
Expand Down
127 changes: 125 additions & 2 deletions clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,47 @@ ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin);
}

static std::vector<std::string>
collectNonISAExtFeature(const std::vector<std::string> &FeaturesNeedOverride,
int XLen) {
auto ParseResult =
llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesNeedOverride);

if (!ParseResult) {
consumeError(ParseResult.takeError());
return std::vector<std::string>();
}

std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();

std::vector<std::string> NonISAExtFeatureVec;

llvm::copy_if(FeaturesNeedOverride, std::back_inserter(NonISAExtFeatureVec),
[&](const std::string &Feat) {
return !llvm::is_contained(ImpliedFeatures, Feat);
});

return NonISAExtFeatureVec;
}

static std::vector<std::string>
resolveTargetAttrOverride(const std::vector<std::string> &FeaturesVec,
int XLen) {
auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
if (I == FeaturesVec.end())
return FeaturesVec;

const std::vector<std::string> FeaturesNeedOverride(FeaturesVec.begin(), I);
std::vector<std::string> NonISAExtFeature =
collectNonISAExtFeature(FeaturesNeedOverride, XLen);

auto ResolvedFeature = std::vector(++I, FeaturesVec.end());
ResolvedFeature.insert(ResolvedFeature.end(), NonISAExtFeature.begin(),
NonISAExtFeature.end());

return ResolvedFeature;
}

bool RISCVTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
Expand All @@ -248,7 +289,10 @@ bool RISCVTargetInfo::initFeatureMap(
Features["32bit"] = true;
}

auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
std::vector<std::string> NewFeaturesVec =
resolveTargetAttrOverride(FeaturesVec, XLen);

auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, NewFeaturesVec);
if (!ParseResult) {
std::string Buffer;
llvm::raw_string_ostream OutputErrMsg(Buffer);
Expand All @@ -262,7 +306,7 @@ bool RISCVTargetInfo::initFeatureMap(
// RISCVISAInfo makes implications for ISA features
std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();
// Add non-ISA features like `relax` and `save-restore` back
for (const std::string &Feature : FeaturesVec)
for (const std::string &Feature : NewFeaturesVec)
if (!llvm::is_contained(ImpliedFeatures, Feature))
ImpliedFeatures.push_back(Feature);

Expand Down Expand Up @@ -359,3 +403,82 @@ void RISCVTargetInfo::fillValidTuneCPUList(
bool Is64Bit = getTriple().isArch64Bit();
llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
}

static void handleFullArchString(StringRef FullArchStr,
std::vector<std::string> &Features) {
Features.push_back("__RISCV_TargetAttrNeedOverride");
auto RII = llvm::RISCVISAInfo::parseArchString(
FullArchStr, /* EnableExperimentalExtension */ true);
if (!RII) {
consumeError(RII.takeError());
// Forward the invalid FullArchStr.
Features.push_back("+" + FullArchStr.str());
} else {
std::vector<std::string> FeatStrings = (*RII)->toFeatureVector();
for (auto FeatString : FeatStrings)
Features.push_back(FeatString);
}
}

ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
ParsedTargetAttr Ret;
if (Features == "default")
return Ret;
SmallVector<StringRef, 1> AttrFeatures;
Features.split(AttrFeatures, ";");
bool FoundArch = false;

for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();
StringRef AttrString = Feature.split("=").second.trim();

if (Feature.startswith("arch=")) {
// Override last features
Ret.Features.clear();
if (FoundArch)
Ret.Duplicate = "arch=";
FoundArch = true;

if (AttrString.startswith("+")) {
// EXTENSION like arch=+v,+zbb
SmallVector<StringRef, 1> Exts;
AttrString.split(Exts, ",");
for (auto Ext : Exts) {
if (Ext.empty())
continue;

StringRef ExtName = Ext.substr(1);
std::string TargetFeature =
llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName);
if (!TargetFeature.empty())
Ret.Features.push_back(Ext.front() + TargetFeature);
else
Ret.Features.push_back(Ext.str());
}
} else {
// full-arch-string like arch=rv64gcv
handleFullArchString(AttrString, Ret.Features);
}
} else if (Feature.startswith("cpu=")) {
if (!Ret.CPU.empty())
Ret.Duplicate = "cpu=";

Ret.CPU = AttrString;

if (!FoundArch) {
// Update Features with CPU's features
StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU);
if (MarchFromCPU != "") {
Ret.Features.clear();
handleFullArchString(MarchFromCPU, Ret.Features);
}
}
} else if (Feature.startswith("tune=")) {
if (!Ret.Tune.empty())
Ret.Duplicate = "tune=";

Ret.Tune = AttrString;
}
}
return Ret;
}
2 changes: 2 additions & 0 deletions clang/lib/Basic/Targets/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ class RISCVTargetInfo : public TargetInfo {
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool isValidTuneCPUName(StringRef Name) const override;
void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool supportsTargetAttributeTune() const override { return true; }
ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
};
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
public:
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3451,6 +3451,11 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unknown << Tune << ParsedAttrs.Tune << Target;

if (Context.getTargetInfo().getTriple().isRISCV() &&
ParsedAttrs.Duplicate != "")
return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
<< Duplicate << None << ParsedAttrs.Duplicate << Target;

if (ParsedAttrs.Duplicate != "")
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Duplicate << None << ParsedAttrs.Duplicate << Target;
Expand Down
10 changes: 10 additions & 0 deletions clang/test/CodeGen/RISCV/riscv-func-attr-target-err.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// REQUIRES: riscv-registered-target
// RUN: not %clang_cc1 -triple riscv64 -target-feature +zifencei -target-feature +m -target-feature +a \
// RUN: -emit-llvm %s 2>&1 | FileCheck %s

// CHECK: error: duplicate 'arch=' in the 'target' attribute string;
__attribute__((target("arch=rv64gc;arch=rv64gc_zbb"))) void testMultiArchSelectLast() {}
// CHECK: error: duplicate 'cpu=' in the 'target' attribute string;
__attribute__((target("cpu=sifive-u74;cpu=sifive-u54"))) void testMultiCpuSelectLast() {}
// CHECK: error: duplicate 'tune=' in the 'target' attribute string;
__attribute__((target("tune=sifive-u74;tune=sifive-u54"))) void testMultiTuneSelectLast() {}
46 changes: 46 additions & 0 deletions clang/test/CodeGen/RISCV/riscv-func-attr-target.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +zifencei -target-feature +m \
// RUN: -target-feature +a -target-feature +save-restore \
// RUN: -emit-llvm %s -o - | FileCheck %s

// CHECK-LABEL: define dso_local void @testDefault
// CHECK-SAME: () #0 {
void testDefault() {}
// CHECK-LABEL: define dso_local void @testMultiAttrStr
// CHECK-SAME: () #1 {
__attribute__((target("cpu=rocket-rv64;tune=generic-rv64;arch=+v"))) void
testMultiAttrStr() {}
// CHECK-LABEL: define dso_local void @testSingleExtension
// CHECK-SAME: () #2 {
__attribute__((target("arch=+zbb"))) void testSingleExtension() {}
// CHECK-LABEL: define dso_local void @testMultiExtension
// CHECK-SAME: () #3 {
__attribute__((target("arch=+zbb,+v,+zicond"))) void testMultiExtension() {}
// CHECK-LABEL: define dso_local void @testFullArch
// CHECK-SAME: () #4 {
__attribute__((target("arch=rv64gc_zbb"))) void testFullArch() {}
// CHECK-LABEL: define dso_local void @testFullArchButSmallThanCmdArch
// CHECK-SAME: () #5 {
__attribute__((target("arch=rv64im"))) void testFullArchButSmallThanCmdArch() {}
// CHECK-LABEL: define dso_local void @testAttrArchAndAttrCpu
// CHECK-SAME: () #6 {
__attribute__((target("cpu=sifive-u54;arch=+zbb"))) void
testAttrArchAndAttrCpu() {}
// CHECK-LABEL: define dso_local void @testAttrFullArchAndAttrCpu
// CHECK-SAME: () #7 {
__attribute__((target("cpu=sifive-u54;arch=rv64im"))) void
testAttrFullArchAndAttrCpu() {}
// CHECK-LABEL: define dso_local void @testAttrCpuOnly
// CHECK-SAME: () #8 {
__attribute__((target("cpu=sifive-u54"))) void testAttrCpuOnly() {}

//.
// CHECK: attributes #0 = { {{.*}}"target-features"="+64bit,+a,+m,+save-restore,+zifencei" }
// CHECK: attributes #1 = { {{.*}}"target-cpu"="rocket-rv64" "target-features"="+64bit,+a,+d,+f,+m,+save-restore,+v,+zicsr,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" "tune-cpu"="generic-rv64" }
// CHECK: attributes #2 = { {{.*}}"target-features"="+64bit,+a,+m,+save-restore,+zbb,+zifencei" }
// CHECK: attributes #3 = { {{.*}}"target-features"="+64bit,+a,+d,+experimental-zicond,+f,+m,+save-restore,+v,+zbb,+zicsr,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" }
// CHECK: attributes #4 = { {{.*}}"target-features"="+64bit,+a,+c,+d,+f,+m,+save-restore,+zbb,+zicsr,+zifencei" }
// CHECK: attributes #5 = { {{.*}}"target-features"="+64bit,+m,+save-restore" }
// CHECK: attributes #6 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+m,+save-restore,+zbb,+zifencei" }
// CHECK: attributes #7 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+m,+save-restore" }
// CHECK: attributes #8 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+c,+d,+f,+m,+save-restore,+zicsr,+zifencei" }
32 changes: 32 additions & 0 deletions lld/test/ELF/lto/loongarch.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
; REQUIRES: loongarch
;; Test we can infer the e_machine value EM_LOONGARCH from a bitcode file.

; RUN: split-file %s %t
; RUN: llvm-as %t/32.ll -o %t/32.o
; RUN: ld.lld %t/32.o -o %t/32
; RUN: llvm-readobj -h %t/32 | FileCheck %s --check-prefixes=CHECK,LA32

; RUN: llvm-as %t/64.ll -o %t/64.o
; RUN: ld.lld %t/64.o -o %t/64
; RUN: llvm-readobj -h %t/64 | FileCheck %s --check-prefixes=CHECK,LA64

; LA32: Class: 32-bit
; LA64: Class: 64-bit
; CHECK: DataEncoding: LittleEndian
; CHECK: Machine: EM_LOONGARCH

;--- 32.ll
target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
target triple = "loongarch32-unknown-elf"

define void @_start() {
ret void
}

;--- 64.ll
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
target triple = "loongarch64-unknown-elf"

define void @_start() {
ret void
}
58 changes: 43 additions & 15 deletions llvm/include/llvm/CodeGen/SelectionDAGISel.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,31 @@ class SelectionDAGISel : public MachineFunctionPass {
enum BuiltinOpcodes {
OPC_Scope,
OPC_RecordNode,
OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7,
OPC_RecordChild0,
OPC_RecordChild1,
OPC_RecordChild2,
OPC_RecordChild3,
OPC_RecordChild4,
OPC_RecordChild5,
OPC_RecordChild6,
OPC_RecordChild7,
OPC_RecordMemRef,
OPC_CaptureGlueInput,
OPC_MoveChild,
OPC_MoveChild0, OPC_MoveChild1, OPC_MoveChild2, OPC_MoveChild3,
OPC_MoveChild4, OPC_MoveChild5, OPC_MoveChild6, OPC_MoveChild7,
OPC_MoveChild0,
OPC_MoveChild1,
OPC_MoveChild2,
OPC_MoveChild3,
OPC_MoveChild4,
OPC_MoveChild5,
OPC_MoveChild6,
OPC_MoveChild7,
OPC_MoveParent,
OPC_CheckSame,
OPC_CheckChild0Same, OPC_CheckChild1Same,
OPC_CheckChild2Same, OPC_CheckChild3Same,
OPC_CheckChild0Same,
OPC_CheckChild1Same,
OPC_CheckChild2Same,
OPC_CheckChild3Same,
OPC_CheckPatternPredicate,
OPC_CheckPatternPredicate2,
OPC_CheckPredicate,
Expand All @@ -144,16 +158,26 @@ class SelectionDAGISel : public MachineFunctionPass {
OPC_CheckType,
OPC_CheckTypeRes,
OPC_SwitchType,
OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
OPC_CheckChild6Type, OPC_CheckChild7Type,
OPC_CheckChild0Type,
OPC_CheckChild1Type,
OPC_CheckChild2Type,
OPC_CheckChild3Type,
OPC_CheckChild4Type,
OPC_CheckChild5Type,
OPC_CheckChild6Type,
OPC_CheckChild7Type,
OPC_CheckInteger,
OPC_CheckChild0Integer, OPC_CheckChild1Integer, OPC_CheckChild2Integer,
OPC_CheckChild3Integer, OPC_CheckChild4Integer,
OPC_CheckCondCode, OPC_CheckChild2CondCode,
OPC_CheckChild0Integer,
OPC_CheckChild1Integer,
OPC_CheckChild2Integer,
OPC_CheckChild3Integer,
OPC_CheckChild4Integer,
OPC_CheckCondCode,
OPC_CheckChild2CondCode,
OPC_CheckValueType,
OPC_CheckComplexPat,
OPC_CheckAndImm, OPC_CheckOrImm,
OPC_CheckAndImm,
OPC_CheckOrImm,
OPC_CheckImmAllOnesV,
OPC_CheckImmAllZerosV,
OPC_CheckFoldableChainNode,
Expand All @@ -172,10 +196,14 @@ class SelectionDAGISel : public MachineFunctionPass {
OPC_EmitNodeXForm,
OPC_EmitNode,
// Space-optimized forms that implicitly encode number of result VTs.
OPC_EmitNode0, OPC_EmitNode1, OPC_EmitNode2,
OPC_EmitNode0,
OPC_EmitNode1,
OPC_EmitNode2,
OPC_MorphNodeTo,
// Space-optimized forms that implicitly encode number of result VTs.
OPC_MorphNodeTo0, OPC_MorphNodeTo1, OPC_MorphNodeTo2,
OPC_MorphNodeTo0,
OPC_MorphNodeTo1,
OPC_MorphNodeTo2,
OPC_CompleteMatch,
// Contains offset in table for pattern being selected
OPC_Coverage
Expand Down
Loading

0 comments on commit 6e10f49

Please sign in to comment.