diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -276,6 +276,11 @@ ``-mfix-cortex-a72-aes-1655431``. The pass is enabled when using either of these cpus with ``-mcpu=`` and can be disabled using ``-mno-fix-cortex-a57-aes-1742098`` or ``-mno-fix-cortex-a72-aes-1655431``. +- Added the ``-fexperimental-max-bitint-width=`` option to increase the maximum + allowed bit width of ``_BitInt`` types beyond the default of 128 bits. Some + operations, such as division or float-to-integer conversion, on ``_BitInt`` + types with more than 128 bits currently crash clang. This option will be + removed in the future once clang supports all such operations. Deprecated Compiler Flags ------------------------- diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -445,6 +445,11 @@ VALUE_LANGOPT(FuchsiaAPILevel, 32, 0, "Fuchsia API level") +// This option will be removed in the future once the backend +// supports all operations (like division or float-to-integer conversion) +// on large _BitInts. +BENIGN_VALUE_LANGOPT(MaxBitIntWidth, 32, 128, "Maximum width of a _BitInt") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -31,6 +31,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Frontend/OpenMP/OMPGridValues.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Error.h" #include "llvm/Support/VersionTuple.h" @@ -235,6 +236,8 @@ unsigned MaxOpenCLWorkGroupSize; + Optional MaxBitIntWidth; + Optional DarwinTargetVariantTriple; // TargetInfo Constructor. Default initializes all fields. @@ -595,11 +598,16 @@ // Different targets may support a different maximum width for the _BitInt // type, depending on what operations are supported. virtual size_t getMaxBitIntWidth() const { + // Consider -fexperimental-max-bitint-width= first. + if (MaxBitIntWidth) + return std::min(*MaxBitIntWidth, llvm::IntegerType::MAX_INT_BITS); + // FIXME: this value should be llvm::IntegerType::MAX_INT_BITS, which is // maximum bit width that LLVM claims its IR can support. However, most - // backends currently have a bug where they only support division - // operations on types that are <= 128 bits and crash otherwise. We're - // setting the max supported value to 128 to be conservative. + // backends currently have a bug where they only support float to int + // conversion (and vice versa) on types that are <= 128 bits and crash + // otherwise. We're setting the max supported value to 128 to be + // conservative. return 128; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6082,6 +6082,12 @@ def fobjc_gc : Flag<["-"], "fobjc-gc">, Group, HelpText<"Enable Objective-C garbage collection">; +def fexperimental_max_bitint_width_EQ: + Joined<["-"], "fexperimental-max-bitint-width=">, Group, + MetaVarName<"">, + HelpText<"Set the maximum bitwidth for _BitInt (this option is expected to be removed in the future)">, + MarshallingInfoInt>; + } // let Flags = [CC1Option, NoDriverOption] //===----------------------------------------------------------------------===// diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -150,6 +150,9 @@ PlatformMinVersion = VersionTuple(); MaxOpenCLWorkGroupSize = 1024; + + MaxBitIntWidth.reset(); + ProgramAddrSpace = 0; } @@ -478,6 +481,9 @@ Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens"; Opts.ProtectParens = false; } + + if (Opts.MaxBitIntWidth) + MaxBitIntWidth = Opts.MaxBitIntWidth; } bool TargetInfo::initFeatureMap( diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -314,7 +314,7 @@ #define BENIGN_LANGOPT(Name, Bits, Default, Description) #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) -#define BENIGN_VALUE_LANGOPT(Name, Type, Bits, Default, Description) +#define BENIGN_VALUE_LANGOPT(Name, Bits, Default, Description) #include "clang/Basic/LangOptions.def" if (ExistingLangOpts.ModuleFeatures != LangOpts.ModuleFeatures) { diff --git a/clang/test/Sema/large-bit-int.c b/clang/test/Sema/large-bit-int.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/large-bit-int.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fexperimental-max-bitint-width=1024 -fsyntax-only -verify %s + +void f() { + _Static_assert(__BITINT_MAXWIDTH__ == 1024, "Macro value is unexpected."); + + _BitInt(1024) a; + unsigned _BitInt(1024) b; + + _BitInt(8388609) c; // expected-error {{signed _BitInt of bit sizes greater than 1024 not supported}} + unsigned _BitInt(0xFFFFFFFFFF) d; // expected-error {{unsigned _BitInt of bit sizes greater than 1024 not supported}} +}