Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 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
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// The ABI to use for passing floating point arguments.
std::string FloatABI;

/// The encoding used for decimal floating point arguments.
std::string DecimalFloatABI;

/// The file to use for dumping bug report by `Debugify` for original
/// debug info.
std::string DIBugsReportFilePath;
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ def err_drv_no_cuda_libdevice : Error<
"cannot find libdevice for %0; provide path to different CUDA installation "
"via '--cuda-path', or pass '-nocudalib' to build without linking with "
"libdevice">;
def err_drv_unsupported_decimal_fp_option_for_target : Error<
"unsupported decimal floating-point option '%0' for this target">;

def err_drv_no_rocm_device_lib : Error<
"cannot find ROCm device library%select{| for %1|for ABI version %1}0; provide its path via "
Expand Down Expand Up @@ -242,6 +244,8 @@ def err_drv_cannot_read_config_file : Error<
"cannot read configuration file '%0': %1">;
def err_drv_arg_requires_bitcode_input: Error<
"option '%0' requires input to be LLVM bitcode">;
def err_drv_invalid_mdecimal_float_abi_EQ: Error<
"invalid argument '%0' to -mdecimal-float-abi=; must be one of: %1">;

def err_target_unsupported_arch
: Error<"the target architecture '%0' is not supported by the target '%1'">;
Expand Down
18 changes: 0 additions & 18 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,6 @@ class TargetInfo : public TransferrableTargetInfo,

std::optional<unsigned> MaxBitIntWidth;

// If disengaged, decimal floating-point extensions are not supported,
// otherwise, the decimal floating-point mode that is enabled.
std::optional<DecimalFloatMode> DecimalFloatEnablementAndMode;

std::optional<llvm::Triple> DarwinTargetVariantTriple;

// TargetInfo Constructor. Default initializes all fields.
Expand Down Expand Up @@ -723,20 +719,6 @@ class TargetInfo : public TransferrableTargetInfo,
/// Determine whether constrained floating point is supported on this target.
virtual bool hasStrictFP() const { return HasStrictFP; }

/// Determine whether decimal floating-point extensions are enabled on this
/// target.
bool hasDecimalFloatingPoint() const {
return DecimalFloatEnablementAndMode.has_value();
}

/// Determine the encoding used for decimal floating-point values on this
/// target if decimal floating-point extensions are enabled.
DecimalFloatMode getDecimalFloatingPointMode() const {
assert(hasDecimalFloatingPoint() &&
"Decimal floating-point extensions are not enabled");
return DecimalFloatEnablementAndMode.value();
}

/// Return the alignment that is the largest alignment ever used for any
/// scalar/SIMD data type on the target machine you are compiling for
/// (including types with an extended alignment requirement).
Expand Down
23 changes: 23 additions & 0 deletions clang/include/clang/Basic/TargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,29 @@ class TargetOptions {

/// The entry point name for HLSL shader being compiled as specified by -E.
std::string HLSLEntry;

// If disengaged, decimal floating-point extensions are not supported,
// otherwise, the decimal floating-point mode is enabled.
std::optional<llvm::DecimalFloatMode> DecimalFloatEnablementAndMode;

/// Determine whether decimal floating-point extensions are enabled on this
/// target.
bool hasDecimalFloatingPoint() const {
return DecimalFloatEnablementAndMode.has_value();
}

/// Determine the encoding used for decimal floating-point values on this
/// target if decimal floating-point extensions are enabled.
llvm::DecimalFloatMode getDecimalFloatingPointMode() const {
assert(hasDecimalFloatingPoint() &&
"Decimal floating-point extensions are not enabled");
return DecimalFloatEnablementAndMode.value();
}

/// Set the encoding used for decimal floating-point value on this target.
void setDecimalFloatingPointMode(llvm::DecimalFloatMode Mode) {
DecimalFloatEnablementAndMode = Mode;
}
};

} // end namespace clang
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4284,6 +4284,11 @@ def malign_double : Flag<["-"], "malign-double">, Group<m_Group>,
MarshallingInfoFlag<LangOpts<"AlignDouble">>;
let Flags = [TargetSpecific] in {
def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>, Values<"soft,softfp,hard">;
def mdecimal_float_abi_EQ : Joined<["-"], "mdecimal-float-abi=">, Group<m_Group>,
Visibility<[ClangOption, CC1Option]>,
Values<"hard,default,libgcc:bid,libgcc:dpd">,
HelpText<"The decimal float encoding to use">,
MarshallingInfoString<CodeGenOpts<"DecimalFloatABI">>;
def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group<m_Group>;
def mfpu_EQ : Joined<["-"], "mfpu=">, Group<m_Group>;
def mhwdiv_EQ : Joined<["-"], "mhwdiv=">, Group<m_Group>;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,9 @@ class ToolChain {
ComputeLLVMTriple(const llvm::opt::ArgList &Args,
types::ID InputType = types::TY_INVALID) const;

void setDecimalFloatABI(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple) const;

/// ComputeEffectiveClangTriple - Return the Clang triple to use for this
/// target, which may take into account the command line arguments. For
/// example, on Darwin the -mmacosx-version-min= command line argument (which
Expand Down
6 changes: 0 additions & 6 deletions clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,12 +524,6 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {

if (Opts.FakeAddressSpaceMap)
AddrSpaceMap = &FakeAddrSpaceMap;

// If decimal floating-point extensions are not enabled at the language
// level, reset the target dependent DFP mode configuration in order to
// avoid surprises.
if (!Opts.DecimalFloatingPoint)
DecimalFloatEnablementAndMode.reset();
}

bool TargetInfo::initFeatureMap(
Expand Down
6 changes: 0 additions & 6 deletions clang/lib/Basic/Targets/OSTargets.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,12 +352,6 @@ class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
case llvm::Triple::x86:
case llvm::Triple::x86_64:
this->HasFloat128 = true;
if (!Triple.isAndroid()) {
// Android NDK r23 and later no longer provide libgcc. DFP support
// for Android is therefore not enabled by default pending the
// availability of a different DFP run-time library.
this->DecimalFloatEnablementAndMode = DecimalFloatMode::BID;
}
break;
}
}
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Basic/Targets/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,11 @@ class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
Int64Type = IsX32 ? SignedLongLong : SignedLong;
RegParmMax = 6;

// TODO
// Here we would test for the value of Opts.DecimalFloatEnablementMode.
// If it is set we would make sure that it has the correct value for this
// target and set the datalayout accordingly.

// Pointers are 32-bit in x32.
resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
"i64:64-f80:128-n8:16:32:64-S128"
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,19 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
.Case("softfp", llvm::FloatABI::Soft)
.Case("hard", llvm::FloatABI::Hard)
.Default(llvm::FloatABI::Default);
// Set decimal float ABI type;
assert((CodeGenOpts.DecimalFloatABI == "hard" ||
CodeGenOpts.DecimalFloatABI == "default " ||
CodeGenOpts.DecimalFloatABI == "libgcc:bid" ||
CodeGenOpts.DecimalFloatABI == "libgcc:dpd" ||
CodeGenOpts.DecimalFloatABI.empty()) &&
"Invalid Decimal Floating Point ABI!");
Options.DecimalFloatABIType =
llvm::StringSwitch<llvm::DecimalFloatABI>(CodeGenOpts.DecimalFloatABI)
.Case("libgcc:bid", llvm::DecimalFloatABI::Libgcc_BID)
.Case("libgcc:dpd", llvm::DecimalFloatABI::Libgcc_DPD)
.Case("hard", llvm::DecimalFloatABI::Hard)
.Default(llvm::DecimalFloatABI::Default);

// Set FP fusion mode.
switch (LangOpts.getDefaultFPContractMode()) {
Expand Down
17 changes: 17 additions & 0 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "clang/Driver/ToolChain.h"
#include "ToolChains/Arch/AArch64.h"
#include "ToolChains/Arch/ARM.h"
#include "ToolChains/Arch/X86.h"
#include "ToolChains/Clang.h"
#include "ToolChains/CommonArgs.h"
#include "ToolChains/Flang.h"
Expand Down Expand Up @@ -922,6 +923,22 @@ bool ToolChain::isThreadModelSupported(const StringRef Model) const {
return false;
}

void ToolChain::setDecimalFloatABI(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple) const {
tools::DecimalFloatABI ABI =
tools::getDecimalFloatABI(getDriver(), Triple, Args);
tools::DecimalFloatABI DefaultDecimalABI =
tools::getDefaultDecimalFloatABI(Triple);
if (DefaultDecimalABI != tools::DecimalFloatABI::None &&
ABI != DefaultDecimalABI) {
Arg *ABIArg =
Args.getLastArg(options::OPT_mdecimal_float_abi_EQ);
assert(ABIArg && "Non-default decimal float abi expected to be from arg");
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< ABIArg->getAsString(Args) << Triple.getTriple();
}
Comment on lines +929 to +940
Copy link
Owner

Choose a reason for hiding this comment

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

Despite the name, this function doesn't seem to actually "set" anything; it only initializes local variables. If it is only intended to validate a supported DFP ABI, then perhaps it should be named checkDecimalFloatABI(). Otherwise, perhaps there should be a FIXME or TODO comment?

Am I correct in assuming the check and diagnostic are sort of placeholder checks for now since they reject any options that are not "none" or the target default? If so, I suggest adding an option to delegate that check to the target (via a virtual function call) with a default base class implementation that does the check above. Alternatively, each target could declare which ABI modes it supports and this function could compare with that list.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not really sure I understand your suggestion here. Are you proposing that a virtual function be added to TargetInfo? From here I don't have any way of getting to the TargetInfo. The decimal floating-point ABI needs to be computed here so that I can fill up the cc1 option. Unless I am not seeing things clearly?

}

std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
types::ID InputType) const {
switch (getTriple().getArch()) {
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@
namespace clang {
namespace driver {
namespace tools {

enum class DecimalFloatABI {
Default, // Target-specific default.
None, // No decimal floating-point support.
Libgcc_BID, // libgcc with BID encoding.
Libgcc_DPD, // libgcc with DPD encoding.
Hard // Target-specific hard ABI.
};
DecimalFloatABI getDecimalFloatABI(const Driver &D,
const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);

DecimalFloatABI getDefaultDecimalFloatABI(const llvm::Triple &Triple);

namespace x86 {

std::string getX86TargetCPU(const Driver &D, const llvm::opt::ArgList &Args,
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,9 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
ArgStringList &CmdArgs) const {
const ToolChain &TC = getToolChain();

// Set the decimal floating-point ABI.
TC.setDecimalFloatABI(Args, EffectiveTriple);

// Add the target features
getTargetFeatures(TC.getDriver(), EffectiveTriple, Args, CmdArgs, false);

Expand Down Expand Up @@ -2818,6 +2821,16 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
switch (optID) {
default:
break;
case options::OPT_mdecimal_float_abi_EQ: {
StringRef Val = A->getValue();
if (Val == "libgcc:bid" || Val == "libgcc:dpd" || Val == "hard") {
CmdArgs.push_back(Args.MakeArgString("-mdecimal-float-abi=" + Val));
} else {
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getSpelling() << Val;
}
break;
}
case options::OPT_ffp_model_EQ: {
// If -ffp-model= is seen, reset to fno-fast-math
HonorINFs = true;
Expand Down
37 changes: 37 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2466,3 +2466,40 @@ void tools::addHIPRuntimeLibArgs(const ToolChain &TC, Compilation &C,
}
}
}

tools::DecimalFloatABI
tools::getDefaultDecimalFloatABI(const llvm::Triple &Triple) {
switch (Triple.getArch()) {
case llvm::Triple::x86_64:
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::arm:
case llvm::Triple::aarch64:
return DecimalFloatABI::Libgcc_BID;
case llvm::Triple::armeb:
case llvm::Triple::thumbeb:
case llvm::Triple::amdgcn:
return DecimalFloatABI::Libgcc_BID;
default:
return DecimalFloatABI::None;
}
}

// Get the decimal float ABI type from the command line arguments
// -mdecimal-float-abi=.
tools::DecimalFloatABI tools::getDecimalFloatABI(const Driver &D,
const llvm::Triple &Triple,
const ArgList &Args) {
tools::DecimalFloatABI ABI = tools::DecimalFloatABI::None;
if (const Arg *A = Args.getLastArg(options::OPT_mdecimal_float_abi_EQ)) {
StringRef Val = A->getValue();
ABI = llvm::StringSwitch<tools::DecimalFloatABI>(Val)
.Case("libgcc:bid", DecimalFloatABI::Libgcc_BID)
.Case("libgcc:dpd", DecimalFloatABI::Libgcc_DPD)
.Case("hard", DecimalFloatABI::Hard)
.Default(DecimalFloatABI::None);
}
if (ABI == DecimalFloatABI::None)
ABI = getDefaultDecimalFloatABI(Triple);
return ABI;
}
20 changes: 20 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4471,6 +4471,25 @@ static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
return Diags.getNumErrors() == NumErrorsBefore;
}

static void SetDFPEnablementMode(TargetOptions & Opts, llvm::Triple T) {
// TODO: Add support for other architectures.
switch (T.getArch()) {
case llvm::Triple::x86:
case llvm::Triple::x86_64:
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::aarch64:
Opts.setDecimalFloatingPointMode(llvm::DecimalFloatMode::BID);
break;
case llvm::Triple::sparc:
Opts.setDecimalFloatingPointMode(llvm::DecimalFloatMode::DPD);
break;
default:
Opts.setDecimalFloatingPointMode(llvm::DecimalFloatMode::None);
break;
}
}

bool CompilerInvocation::CreateFromArgsImpl(
CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs,
DiagnosticsEngine &Diags, const char *Argv0) {
Expand Down Expand Up @@ -4510,6 +4529,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
InputKind DashX = Res.getFrontendOpts().DashX;
ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
llvm::Triple T(Res.getTargetOpts().Triple);
SetDFPEnablementMode(Res.getTargetOpts(), T);
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
Res.getFileSystemOpts().WorkingDir);

Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,7 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
// C23 decimal floating point extensions.
// FIXME: Define to 202311L when support for C23 decimal floating point
// FIXME: extensions is feature complete.
if (!LangOpts.CPlusPlus && LangOpts.DecimalFloatingPoint &&
TI.hasDecimalFloatingPoint())
if (!LangOpts.CPlusPlus && LangOpts.DecimalFloatingPoint)
Builder.defineMacro("__STDC_IEC_60559_DFP__", "197001L");

if (LangOpts.ObjC)
Expand Down
4 changes: 0 additions & 4 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4865,10 +4865,6 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
Diag(AttrLoc, diag::err_dfp_disabled);
return;
}
if (!Context.getTargetInfo().hasDecimalFloatingPoint()) {
Diag(AttrLoc, diag::err_dfp_not_supported);
return;
}
}

if (ComplexMode) {
Expand Down
4 changes: 0 additions & 4 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1592,10 +1592,6 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_dfp_disabled);
Result = Context.IntTy;
declarator.setInvalidType(true);
} else if (!S.Context.getTargetInfo().hasDecimalFloatingPoint()) {
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_dfp_not_supported);
Result = Context.IntTy;
declarator.setInvalidType(true);
} else {
Result = TSTToDecimalFloatType(Context, DS.getTypeSpecType());
}
Expand Down
29 changes: 29 additions & 0 deletions clang/test/Driver/decimal-float-abi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// DEFINE: %{common_opts_x86} = -### \
// DEFINE: -fexperimental-decimal-floating-point

// X86
// RUN: %clang %{common_opts_x86} --target=x86_64 \
// RUN: -mdecimal-float-abi=libgcc:bid %s 2>&1 | FileCheck -check-prefix=BID %s

// RUN: not %clang %{common_opts_x86} --target=x86_64 \
// RUN: -mdecimal-float-abi=libgcc:dpd %s 2>&1 \
// RUN: | FileCheck -check-prefix=ERROR_DPD %s

// RUN: not %clang %{common_opts_x86} --target=x86_64 \
// RUN: -mdecimal-float-abi=hard %s 2>&1 \
// RUN: | FileCheck -check-prefix=ERROR_HARD %s

// RUN: %clang %{common_opts_x86} --target=mips64-unknown-linux \
// RUN: -mdecimal-float-abi=hard %s 2>&1 \
// RUN: | FileCheck -check-prefix=HARD %s

// BID: "-mdecimal-float-abi=libgcc:bid" {{.*}}
// HARD: "-mdecimal-float-abi=hard" {{.*}}

// ERROR_DPD: unsupported option '-mdecimal-float-abi=libgcc:dpd' for target 'x86_64'
// ERROR_HARD: unsupported option '-mdecimal-float-abi=hard' for target 'x86_64'
// ERROR_MIPS_TRGT: unsupported option '-mdecimal-float-abi=' for target 'mips64-unknown-linux'

// PPC
// S390
// ARM
Loading