Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
27 changes: 0 additions & 27 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,15 +220,6 @@ enum OpenCLTypeKind : uint8_t {
OCLTK_Sampler,
};

// ISO/IEC TS 18661-2, ISO/IEC TR 24733, and C23 decimal floating-point.
// Multiple encoding forms for the storage of decimal floating-point values
// have been defined for use on various platforms. This enumeration provides
// an enumerator for each known encoding.
enum class DecimalFloatMode : uint8_t {
BID, // Binary Integer Decimal.
DPD, // Densely Packed Decimal.
};

/// Exposes information about the current target.
///
class TargetInfo : public TransferrableTargetInfo,
Expand Down Expand Up @@ -287,10 +278,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 +710,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
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
17 changes: 14 additions & 3 deletions clang/lib/Basic/Targets/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,12 +363,23 @@ class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {
public:
PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: PPCTargetInfo(Triple, Opts) {
std::string EncodedLayout;
if (Opts.hasDecimalFloatingPoint()) {
const llvm::DecimalFloatMode Encoding =
Opts.getDecimalFloatingPointMode();
assert(Encoding == llvm::DecimalFloatMode::BID &&
"wrong decimal floating-point encoding for powerpc target");
EncodedLayout = "d:bid-m";
} else {
EncodedLayout = "m";
}

if (Triple.isOSAIX())
resetDataLayout("E-m:a-p:32:32-Fi32-i64:64-n32");
resetDataLayout("E-" + EncodedLayout + ":a-p:32:32-Fi32-i64:64-n32");
else if (Triple.getArch() == llvm::Triple::ppcle)
resetDataLayout("e-m:e-p:32:32-Fn32-i64:64-n32");
resetDataLayout("e" + EncodedLayout + ":e-p:32:32-Fn32-i64:64-n32");
else
resetDataLayout("E-m:e-p:32:32-Fn32-i64:64-n32");
resetDataLayout("E" + EncodedLayout + ":e-p:32:32-Fn32-i64:64-n32");

switch (getTriple().getOS()) {
case llvm::Triple::Linux:
Expand Down
22 changes: 16 additions & 6 deletions clang/lib/Basic/Targets/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,13 +719,23 @@ class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
Int64Type = IsX32 ? SignedLongLong : SignedLong;
RegParmMax = 6;

std::string EncodedLayout;
if (Opts.hasDecimalFloatingPoint()) {
const llvm::DecimalFloatMode Encoding =
Opts.getDecimalFloatingPointMode();
assert(Encoding == llvm::DecimalFloatMode::BID &&
"wrong decimal floating-point encoding for x86_64 target");
EncodedLayout = "e-d:bid";
} else {
EncodedLayout = "e";
}
std::string Layout =
"-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128";

// 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"
: IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:"
"64-i64:64-f80:128-n8:16:32:64-S128"
: "e-m:e-p270:32:32-p271:32:32-p272:64:"
"64-i64:64-f80:128-n8:16:32:64-S128");
resetDataLayout(IsX32 ? EncodedLayout + "-m:e-p:32:32" + Layout
: IsWinCOFF ? EncodedLayout + "-m:w" + Layout
: EncodedLayout + "-m:e" + Layout);

// Use fpret only for long double.
RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,13 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
break;
}

if (LangOpts.DecimalFloatingPoint) {
if (TargetOpts.getDecimalFloatingPointMode() == llvm::DecimalFloatMode::BID)
Options.DFPEncoding = llvm::DecimalFloatMode::BID;
else if (TargetOpts.getDecimalFloatingPointMode() ==
llvm::DecimalFloatMode::DPD)
Options.DFPEncoding = llvm::DecimalFloatMode::DPD;
}
Options.BinutilsVersion =
llvm::TargetMachine::parseBinutilsVersion(CodeGenOpts.BinutilsVersion);
Options.UseInitArray = CodeGenOpts.UseInitArray;
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }
void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }

bool CompilerInstance::createTarget() {
if (getLangOpts().DecimalFloatingPoint) {
if (getInvocation().getTargetOpts().CPU == "x86" ||
getInvocation().getTargetOpts().CPU == "x86-64" ||
getInvocation().getTargetOpts().CPU == "powerpc")
getInvocation().getTargetOpts().setDecimalFloatingPointMode(
llvm::DecimalFloatMode::BID);
else
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't know that this logic is correct for most targets.

libdfp only mentions x86(-64), PPC and s390 in its documentation (see https://github.com/libdfp/libdfp), but helpfully, the most recent commit suggests that aarch64 is going to go with BID.

The AArch64 suggests that it's using BID: https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#decimal-floating-point (there's nothing corresponding I could find for 32-bit arm).

Copy link
Owner

Choose a reason for hiding this comment

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

It isn't right. I suspect Zahira derived this from similar code I added to the LinuxTargetInfo constructor in clang/lib/Basic/Targets/OSTargets.h. I'm still working on code to enable proper target dependent enablement. I've been taking forever to get that done.

I think our plan for prior to upstreaming should be to focus on just Intel support (perhaps IBM too given Ariel's involvement) and then let maintainers for other architectures enable support for other targets following appropriate testing after our changes are accepted upstream.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Again the change you are suggesting implies that the encoding info is in TargetInfo but I don't think we can do that there. See comments above.

getInvocation().getTargetOpts().setDecimalFloatingPointMode(
llvm::DecimalFloatMode::DPD);
}
// Create the target instance.
setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
getInvocation().TargetOpts));
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
7 changes: 1 addition & 6 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1592,13 +1592,8 @@ 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 {
} else
Result = TSTToDecimalFloatType(Context, DS.getTypeSpecType());
}
break;
case DeclSpec::TST_class:
case DeclSpec::TST_enum:
Expand Down
25 changes: 25 additions & 0 deletions clang/test/CodeGen/dfp-dl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// DEFINE: %{common_opts_x86} = -triple x86_64 -target-cpu x86-64 \
// DEFINE: -emit-llvm -o -

// RUN: %clang_cc1 %{common_opts_x86} %s | FileCheck %s --check-prefix=CHECK_x86

// RUN: %clang_cc1 %{common_opts_x86} -fexperimental-decimal-floating-point %s \
// RUN: | FileCheck %s --check-prefix=DFP_x86

// DEFINE: %{common_opts_ppc} = -triple powerpc-unknown-aix \
// DEFINE: -target-cpu powerpc -emit-llvm -o -

// RUN: %clang_cc1 %{common_opts_ppc} %s | FileCheck %s \
// RUN: --check-prefixes=CHECK_PPC

// RUN: %clang_cc1 %{common_opts_ppc} -fexperimental-decimal-floating-point %s \
// RUN: | FileCheck %s --check-prefixes=DFP_PPC

// CHECK_x86: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
// DFP_x86: target datalayout = "e-d:bid-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"

// CHECK_PPC: target datalayout = "E-m:a-p:32:32-Fi32-i64:64-n32"
// DFP_PPC: target datalayout = "E-d:bid-m:a-p:32:32-Fi32-i64:64-n32"

void foo() {
}
10 changes: 10 additions & 0 deletions llvm/include/llvm/ADT/FloatingPointMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,16 @@ FPClassTest unknown_sign(FPClassTest Mask);
/// Write a human readable form of \p Mask to \p OS
raw_ostream &operator<<(raw_ostream &OS, FPClassTest Mask);

// ISO/IEC TS 18661-2, ISO/IEC TR 24733, and C23 decimal floating-point.
// Multiple encoding forms for the storage of decimal floating-point values
// have been defined for use on various platforms. This enumeration provides
// an enumerator for each known encoding.
enum class DecimalFloatMode : uint8_t {
BID, // Binary Integer Decimal.
DPD, // Densely Packed Decimal.
None // No decimal floating-point in target.
};

} // namespace llvm

#endif // LLVM_ADT_FLOATINGPOINTMODE_H
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/DataLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Alignment.h"
Expand Down Expand Up @@ -119,6 +120,8 @@ class DataLayout {
/// Defaults to false.
bool BigEndian;

llvm::DecimalFloatMode DFPEncoding;

unsigned AllocaAddrSpace;
MaybeAlign StackNaturalAlign;
unsigned ProgramAddrSpace;
Expand Down Expand Up @@ -205,6 +208,7 @@ class DataLayout {
clear();
StringRepresentation = DL.StringRepresentation;
BigEndian = DL.isBigEndian();
DFPEncoding = DL.DFPEncoding;
AllocaAddrSpace = DL.AllocaAddrSpace;
StackNaturalAlign = DL.StackNaturalAlign;
FunctionPtrAlign = DL.FunctionPtrAlign;
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/Target/TargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ namespace llvm {
/// Which debugger to tune for.
DebuggerKind DebuggerTuning = DebuggerKind::Default;

llvm::DecimalFloatMode DFPEncoding = llvm::DecimalFloatMode::None;

private:
/// Flushing mode to assume in default FP environment.
DenormalMode FPDenormalMode;
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/IR/DataLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ void DataLayout::reset(StringRef Desc) {

LayoutMap = nullptr;
BigEndian = false;
DFPEncoding = llvm::DecimalFloatMode::None;
AllocaAddrSpace = 0;
StackNaturalAlign.reset();
ProgramAddrSpace = 0;
Expand Down Expand Up @@ -318,6 +319,14 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
case 'e':
BigEndian = false;
break;
case 'd':
if (Split.second == "bid")
DFPEncoding = llvm::DecimalFloatMode::BID;
else if (Split.second == "dpd")
DFPEncoding = llvm::DecimalFloatMode::DPD;
else
DFPEncoding = llvm::DecimalFloatMode::None;
break;
case 'p': {
// Address space.
unsigned AddrSpace = 0;
Expand Down
12 changes: 10 additions & 2 deletions llvm/lib/Target/X86/X86TargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,18 @@ static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
return std::make_unique<X86ELFTargetObjectFile>();
}

static std::string computeDataLayout(const Triple &TT) {
static std::string computeDataLayout(const Triple &TT,
const TargetOptions &Options) {
// X86 is little endian
std::string Ret = "e";

// Decimal floating-point encoding.
if (Options.DFPEncoding != llvm::DecimalFloatMode::None) {
assert(Options.DFPEncoding == llvm::DecimalFloatMode::BID &&
"Decimal floating-point on x86 is BID!");
Ret += "-d:bid";
}

Ret += DataLayout::getManglingComponent(TT);
// X86 and x32 have 32 bit pointers.
if (!TT.isArch64Bit() || TT.isX32() || TT.isOSNaCl())
Expand Down Expand Up @@ -226,7 +234,7 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
: LLVMTargetMachine(
T, computeDataLayout(TT), TT, CPU, FS, Options,
T, computeDataLayout(TT, Options), TT, CPU, FS, Options,
getEffectiveRelocModel(TT, JIT, RM),
getEffectiveX86CodeModel(CM, JIT, TT.getArch() == Triple::x86_64),
OL),
Expand Down