Skip to content
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

[RISCV] Support __builtin_cpu_is #116231

Merged
merged 22 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed .icslock
Empty file.
5 changes: 2 additions & 3 deletions bolt/unittests/Core/MCPlusBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,14 @@ INSTANTIATE_TEST_SUITE_P(AArch64, MCPlusBuilderTester,
::testing::Values(Triple::aarch64));

TEST_P(MCPlusBuilderTester, AliasX0) {
uint64_t AliasesX0[] = {AArch64::W0, AArch64::W0_HI,
AArch64::X0, AArch64::W0_W1,
uint64_t AliasesX0[] = {AArch64::W0, AArch64::X0, AArch64::W0_W1,
AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7};
size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0);
testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count);
}

TEST_P(MCPlusBuilderTester, AliasSmallerX0) {
uint64_t AliasesX0[] = {AArch64::W0, AArch64::W0_HI, AArch64::X0};
uint64_t AliasesX0[] = {AArch64::W0, AArch64::X0};
size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0);
testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count, true);
}
Expand Down
1 change: 0 additions & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,6 @@ X86 Support
- Support ISA of ``AMX-MOVRS``.
- Support ISA of ``AMX-AVX512``.
- Support ISA of ``AMX-TF32``.
- Support ISA of ``MOVRS``.

Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
5 changes: 1 addition & 4 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,6 @@ def TargetELF : TargetSpec {
def TargetELFOrMachO : TargetSpec {
let ObjectFormats = ["ELF", "MachO"];
}
def TargetIFuncSupport : TargetSpec {
let CustomCode = [{ Target.supportsIFunc() }];
}
def TargetWindowsArm64EC : TargetSpec {
let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }];
}
Expand Down Expand Up @@ -1858,7 +1855,7 @@ def IBOutletCollection : InheritableAttr {
let Documentation = [Undocumented];
}

def IFunc : Attr, TargetSpecificAttr<TargetIFuncSupport> {
def IFunc : Attr, TargetSpecificAttr<TargetELFOrMachO> {
let Spellings = [GCC<"ifunc">];
let Args = [StringArgument<"Resolver">];
let Subjects = SubjectList<[Function]>;
Expand Down
19 changes: 6 additions & 13 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -6051,19 +6051,12 @@ declared entity. The entity must not have weak linkage; for example, in C++,
it cannot be applied to a declaration if a definition at that location would be
considered inline.

Not all targets support this attribute:

- ELF target support depends on both the linker and runtime linker, and is
available in at least lld 4.0 and later, binutils 2.20.1 and later, glibc
v2.11.1 and later, and FreeBSD 9.1 and later.
- Mach-O targets support it, but with slightly different semantics: the resolver
is run at first call, instead of at load time by the runtime linker.
- Windows target supports it on AArch64, but with different semantics: the
``ifunc`` is replaced with a global function pointer, and the call is replaced
with an indirect call. The function pointer is initialized by a constructor
that calls the resolver.
- Baremetal target supports it on AVR.
- Other targets currently do not support this attribute.
Not all targets support this attribute. ELF target support depends on both the
linker and runtime linker, and is available in at least lld 4.0 and later,
binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
Mach-O targets support it, but with slightly different semantics: the resolver
is run at first call, instead of at load time by the runtime linker. Targets
other than ELF and Mach-O currently do not support this attribute.
}];
}

Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Basic/BuiltinsX86.def
Original file line number Diff line number Diff line change
Expand Up @@ -660,9 +660,6 @@ TARGET_BUILTIN(__builtin_ia32_vpdpbuud256, "V8iV8iV8iV8i", "ncV:256:", "avxvnnii
TARGET_BUILTIN(__builtin_ia32_vpdpbuuds128, "V4iV4iV4iV4i", "ncV:128:", "avxvnniint8|avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vpdpbuuds256, "V8iV8iV8iV8i", "ncV:256:", "avxvnniint8|avx10.2-256")

// MOVRS
TARGET_BUILTIN(__builtin_ia32_prefetchrs, "vvC*", "nc", "movrs")

TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2OiUcIi", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2OiV2OivC*V2OiUcIi", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4dvC*V4OiUcIi", "nV:256:", "avx512vl")
Expand Down
6 changes: 0 additions & 6 deletions clang/include/clang/Basic/BuiltinsX86_64.def
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,6 @@ TARGET_BUILTIN(__builtin_ia32_aand64, "vv*SOi", "n", "raoint")
TARGET_BUILTIN(__builtin_ia32_aor64, "vv*SOi", "n", "raoint")
TARGET_BUILTIN(__builtin_ia32_axor64, "vv*SOi", "n", "raoint")

// MOVRS
TARGET_BUILTIN(__builtin_ia32_movrsqi, "ScvC*", "n", "movrs")
TARGET_BUILTIN(__builtin_ia32_movrshi, "SsvC*", "n", "movrs")
TARGET_BUILTIN(__builtin_ia32_movrssi, "SivC*", "n", "movrs")
TARGET_BUILTIN(__builtin_ia32_movrsdi, "SLLivC*", "n", "movrs")

// MOVRS and AVX10.2
TARGET_BUILTIN(__builtin_ia32_vmovrsb128, "V16cV16cC*", "nV:128:", "movrs,avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vmovrsb256, "V32cV32cC*", "nV:256:", "movrs,avx10.2-256")
Expand Down
4 changes: 0 additions & 4 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1497,10 +1497,6 @@ class TargetInfo : public TransferrableTargetInfo,
bool supportsIFunc() const {
if (getTriple().isOSBinFormatMachO())
return true;
if (getTriple().isOSWindows() && getTriple().isAArch64())
return true;
if (getTriple().getArch() == llvm::Triple::ArchType::avr)
return true;
return getTriple().isOSBinFormatELF() &&
((getTriple().isOSLinux() && !getTriple().isMusl()) ||
getTriple().isOSFreeBSD());
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/arm_sve.td
Original file line number Diff line number Diff line change
Expand Up @@ -1964,7 +1964,7 @@ let SVETargetGuard = "sve2,lut,bf16", SMETargetGuard = "sme2,lut,bf16" in {
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Optional

let SVETargetGuard = "sve2,sve-aes", SMETargetGuard = InvalidMode in {
let SVETargetGuard = "sve2-aes", SMETargetGuard = InvalidMode in {
def SVAESD : SInst<"svaesd[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_aesd", [IsOverloadNone]>;
def SVAESIMC : SInst<"svaesimc[_{d}]", "dd", "Uc", MergeNone, "aarch64_sve_aesimc", [IsOverloadNone]>;
def SVAESE : SInst<"svaese[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_aese", [IsOverloadNone]>;
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasSVE2p1)
Builder.defineMacro("__ARM_FEATURE_SVE2p1", "1");

if (HasSVE2 && HasSVEAES)
if (HasSVE2 && HasSVE2AES)
Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");

if (HasSVE2 && HasSVE2BitPerm)
Expand Down Expand Up @@ -769,7 +769,7 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
.Case("f32mm", FPU & SveMode && HasMatmulFP32)
.Case("f64mm", FPU & SveMode && HasMatmulFP64)
.Case("sve2", FPU & SveMode && HasSVE2)
.Case("sve-aes", HasSVEAES)
.Case("sve2-pmull128", FPU & SveMode && HasSVE2AES)
.Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm)
.Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
.Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
Expand Down Expand Up @@ -861,10 +861,12 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasSVE2 = true;
HasSVE2p1 = true;
}
if (Feature == "+sve-aes") {
if (Feature == "+sve2-aes") {
FPU |= NeonMode;
FPU |= SveMode;
HasFullFP16 = true;
HasSVEAES = true;
HasSVE2 = true;
HasSVE2AES = true;
}
if (Feature == "+sve2-sha3") {
FPU |= NeonMode;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/AArch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
bool HasBFloat16 = false;
bool HasSVE2 = false;
bool HasSVE2p1 = false;
bool HasSVEAES = false;
bool HasSVE2AES = false;
bool HasSVE2SHA3 = false;
bool HasSVE2SM4 = false;
bool HasSVEB16B16 = false;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,3 +508,10 @@ bool RISCVTargetInfo::validateGlobalRegisterVariable(
}
return false;
}

bool RISCVTargetInfo::validateCpuIs(StringRef CPUName) const {
assert(getTriple().isOSLinux() &&
"__builtin_cpu_is() is only supported for Linux.");

return llvm::RISCV::hasValidCPUModel(CPUName);
}
2 changes: 2 additions & 0 deletions clang/lib/Basic/Targets/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ class RISCVTargetInfo : public TargetInfo {
}

bool supportsCpuSupports() const override { return getTriple().isOSLinux(); }
bool supportsCpuIs() const override { return getTriple().isOSLinux(); }
bool supportsCpuInit() const override { return getTriple().isOSLinux(); }
bool validateCpuSupports(StringRef Feature) const override;
bool validateCpuIs(StringRef CPUName) const override;
bool isValidFeatureName(StringRef Name) const override;

bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
Expand Down
50 changes: 50 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/TargetParser/AArch64TargetParser.h"
#include "llvm/TargetParser/RISCVISAInfo.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
#include "llvm/TargetParser/X86TargetParser.h"
#include <optional>
#include <sstream>
Expand Down Expand Up @@ -22505,6 +22506,53 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID,
return nullptr;
}

Value *CodeGenFunction::EmitRISCVCpuIs(const CallExpr *E) {
const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
return EmitRISCVCpuIs(CPUStr);
}

Value *CodeGenFunction::EmitRISCVCpuIs(StringRef CPUStr) {
llvm::Type *Int32Ty = Builder.getInt32Ty();
llvm::Type *Int64Ty = Builder.getInt64Ty();
llvm::Type *StructTy = llvm::StructType::get(Int32Ty, Int64Ty, Int64Ty);
llvm::Constant *RISCVCPUModel =
CGM.CreateRuntimeVariable(StructTy, "__riscv_cpu_model");
cast<llvm::GlobalValue>(RISCVCPUModel)->setDSOLocal(true);

auto loadRISCVCPUID = [&](unsigned Index, llvm::Type *ValueTy,
CGBuilderTy &Builder, CodeGenModule &CGM) {
wangpc-pp marked this conversation as resolved.
Show resolved Hide resolved
llvm::Value *GEPIndices[] = {Builder.getInt32(0),
llvm::ConstantInt::get(Int32Ty, Index)};
Value *Ptr = Builder.CreateInBoundsGEP(StructTy, RISCVCPUModel, GEPIndices);
wangpc-pp marked this conversation as resolved.
Show resolved Hide resolved
Value *CPUID = Builder.CreateAlignedLoad(
ValueTy, Ptr,
CharUnits::fromQuantity(ValueTy->getScalarSizeInBits() / 8));
wangpc-pp marked this conversation as resolved.
Show resolved Hide resolved
return CPUID;
};

const llvm::RISCV::CPUModel CPUModel = llvm::RISCV::getCPUModel(CPUStr);

// Compare mvendorid.
Value *VendorID = loadRISCVCPUID(0, Int32Ty, Builder, CGM);
Value *Result = Builder.CreateICmpEQ(
VendorID, llvm::ConstantInt::get(Int32Ty, CPUModel.MVendorID));
wangpc-pp marked this conversation as resolved.
Show resolved Hide resolved

// Compare marchid.
Value *ArchID = loadRISCVCPUID(1, Int64Ty, Builder, CGM);
Result = Builder.CreateAnd(
Result, Builder.CreateICmpEQ(
ArchID, llvm::ConstantInt::get(Int64Ty, CPUModel.MArchID)));

// Compare mimplid.
wangpc-pp marked this conversation as resolved.
Show resolved Hide resolved
Value *ImplID = loadRISCVCPUID(2, Int64Ty, Builder, CGM);
Result = Builder.CreateAnd(
Result, Builder.CreateICmpEQ(
ImplID, llvm::ConstantInt::get(Int64Ty, CPUModel.MImpID)));

return Result;
}

Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
const CallExpr *E,
ReturnValueSlot ReturnValue) {
Expand All @@ -22513,6 +22561,8 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
return EmitRISCVCpuSupports(E);
if (BuiltinID == Builtin::BI__builtin_cpu_init)
return EmitRISCVCpuInit();
if (BuiltinID == Builtin::BI__builtin_cpu_is)
return EmitRISCVCpuIs(E);

SmallVector<Value *, 4> Ops;
llvm::Type *ResultType = ConvertType(E->getType());
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4730,6 +4730,8 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::Value *EmitRISCVCpuSupports(const CallExpr *E);
llvm::Value *EmitRISCVCpuSupports(ArrayRef<StringRef> FeaturesStrs);
llvm::Value *EmitRISCVCpuInit();
llvm::Value *EmitRISCVCpuIs(const CallExpr *E);
llvm::Value *EmitRISCVCpuIs(StringRef CPUStr);

void AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst,
const CallExpr *E);
Expand Down
66 changes: 11 additions & 55 deletions clang/lib/Driver/ToolChains/PS4CPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ void tools::PS4cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(
Args.MakeArgString(Twine("-lto-debug-options=") + LTOArgs));

// Sanitizer runtimes must be supplied before all other objects and libs.
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
TC.addSanitizerArgs(Args, CmdArgs, "-l", "");

Expand Down Expand Up @@ -361,70 +360,27 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (StringRef Jobs = getLTOParallelism(Args, D); !Jobs.empty())
AddLTOFlag(Twine("jobs=") + Jobs);

if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
TC.addSanitizerArgs(Args, CmdArgs, "-l", "");

TC.AddFilePathLibArgs(Args, CmdArgs);
Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
options::OPT_s, options::OPT_t});

if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
CmdArgs.push_back("--no-demangle");

// Sanitizer runtimes must be supplied before all other objects and libs.
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
TC.addSanitizerArgs(Args, CmdArgs, "-l", "");

const bool AddStartFiles =
!Relocatable &&
!Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib);

auto AddCRTObject = [&](const char *Name) {
CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(Name)));
};

if (AddStartFiles) {
if (!Shared)
AddCRTObject("crt1.o");
AddCRTObject("crti.o");
AddCRTObject(Shared ? "crtbeginS.o"
: Static ? "crtbeginT.o"
: "crtbegin.o");
}

AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);

if (!Relocatable &&
!Args.hasArg(options::OPT_nodefaultlibs, options::OPT_nostdlib)) {

if (UseJMC) {
CmdArgs.push_back("--push-state");
CmdArgs.push_back("--whole-archive");
CmdArgs.push_back("-lSceJmc_nosubmission");
CmdArgs.push_back("--pop-state");
}

if (Args.hasArg(options::OPT_pthread))
CmdArgs.push_back("-lpthread");

if (Static) {
if (!Args.hasArg(options::OPT_nostdlibxx))
CmdArgs.push_back("-lstdc++");
if (!Args.hasArg(options::OPT_nolibc)) {
CmdArgs.push_back("-lm");
CmdArgs.push_back("-lc");
}

CmdArgs.push_back("-lcompiler_rt");
CmdArgs.push_back("-lkernel");
} else {
// The C and C++ libraries are combined.
if (!Args.hasArg(options::OPT_nolibc, options::OPT_nostdlibxx))
CmdArgs.push_back("-lc_stub_weak");

CmdArgs.push_back("-lkernel_stub_weak");
}
if (Args.hasArg(options::OPT_pthread)) {
CmdArgs.push_back("-lpthread");
}
if (AddStartFiles) {
AddCRTObject(Shared ? "crtendS.o" : "crtend.o");
AddCRTObject("crtn.o");

if (UseJMC) {
CmdArgs.push_back("--push-state");
CmdArgs.push_back("--whole-archive");
CmdArgs.push_back("-lSceJmc_nosubmission");
CmdArgs.push_back("--pop-state");
}

if (Args.hasArg(options::OPT_fuse_ld_EQ)) {
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Headers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ set(x86_files
movdirintrin.h
movrs_avx10_2_512intrin.h
movrs_avx10_2intrin.h
movrsintrin.h
mwaitxintrin.h
nmmintrin.h
pconfigintrin.h
Expand Down
4 changes: 0 additions & 4 deletions clang/lib/Headers/immintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,10 +605,6 @@ _storebe_i64(void * __P, long long __D) {
#include <movdirintrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || defined(__MOVRS__)
#include <movrsintrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || \
(defined(__AVX10_2__) && defined(__MOVRS__))
#include <movrs_avx10_2intrin.h>
Expand Down
Loading
Loading