diff --git a/.github/workflows/gh_pages.yml b/.github/workflows/gh_pages.yml index a50bb710c3dbe..8a0f751998d80 100644 --- a/.github/workflows/gh_pages.yml +++ b/.github/workflows/gh_pages.yml @@ -7,6 +7,7 @@ on: jobs: build: runs-on: ubuntu-latest + if: github.repository == 'intel/llvm' steps: - uses: actions/checkout@v2 with: diff --git a/.gitignore b/.gitignore index ce18cfcde8751..9fbbe9cfc0dd3 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,8 @@ autoconf/autom4te.cache # VS2017 and VSCode config files. .vscode .vs +# pythonenv for github Codespaces +pythonenv* # clangd index. (".clangd" is a config file now, thus trailing slash) .clangd/ .cache diff --git a/buildbot/dependency.conf b/buildbot/dependency.conf index 109c3859d5361..360edd747e86f 100644 --- a/buildbot/dependency.conf +++ b/buildbot/dependency.conf @@ -7,8 +7,8 @@ ocl_cpu_rt_ver_win=2020.11.8.0.27 # https://github.com/intel/compute-runtime/releases/tag/20.35.17767 ocl_gpu_rt_ver=20.35.17767 # Same GPU driver supports Level Zero and OpenCL: -# https://downloadmirror.intel.com/29817/a08/igfx_win10_100.8673.zip -ocl_gpu_rt_ver_win=27.20.100.8673 +# https://downloadmirror.intel.com/29879/a08/igfx_win10_100.8778.zip +ocl_gpu_rt_ver_win=27.20.100.8778 intel_sycl_ver=build # https://github.com/oneapi-src/oneTBB/releases/download/v2021.1-beta08/oneapi-tbb-2021.1-beta08-lin.tgz tbb_ver=2021.1.9.636 @@ -25,7 +25,7 @@ fpga_ver_win=20200811_000006 cpu_driver_lin=2020.11.8.0.27 cpu_driver_win=2020.11.8.0.27 gpu_driver_lin=20.35.17767 -gpu_driver_win=27.20.100.8673 +gpu_driver_win=27.20.100.8778 fpga_driver_lin=2020.11.8.0.27 fpga_driver_win=2020.11.8.0.27 # NVidia CUDA driver diff --git a/buildbot/dependency.py b/buildbot/dependency.py index 253891b8a6bdd..21ee9258871d5 100644 --- a/buildbot/dependency.py +++ b/buildbot/dependency.py @@ -58,7 +58,10 @@ def do_dependency(args): # fetch and build OpenCL ICD loader icd_loader_dir = os.path.join(args.obj_dir, "OpenCL-ICD-Loader") if not os.path.isdir(icd_loader_dir): - clone_cmd = ["git", "clone", "https://github.com/KhronosGroup/OpenCL-ICD-Loader", "OpenCL-ICD-Loader"] + clone_cmd = ["git", "clone", + "https://github.com/KhronosGroup/OpenCL-ICD-Loader", + "OpenCL-ICD-Loader", "-b", "v2020.06.16"] + subprocess.check_call(clone_cmd, cwd=args.obj_dir) else: fetch_cmd = ["git", "pull", "--ff", "--ff-only", "origin"] diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp index 04dc61f02df1e..44ae380b63b2e 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp @@ -338,7 +338,7 @@ void UseAutoCheck::replaceIterators(const DeclStmt *D, ASTContext *Context) { // Drill down to the as-written initializer. const Expr *E = (*Construct->arg_begin())->IgnoreParenImpCasts(); - if (E != E->IgnoreConversionOperator()) { + if (E != E->IgnoreConversionOperatorSingleStep()) { // We hit a conversion operator. Early-out now as they imply an implicit // conversion from a different type. Could also mean an explicit // conversion from the same type but that's pretty rare. diff --git a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp index 9dcb10b9d20c4..7e8ba4eb90c65 100644 --- a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp @@ -205,7 +205,7 @@ std::string compareExpressionToZero(const MatchFinder::MatchResult &Result, std::string replacementExpression(const MatchFinder::MatchResult &Result, bool Negated, const Expr *E) { - E = E->ignoreParenBaseCasts(); + E = E->IgnoreParenBaseCasts(); if (const auto *EC = dyn_cast(E)) E = EC->getSubExpr(); diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-redundant-branch-condition.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-redundant-branch-condition.rst index 8bc97f4114ae5..c2746914e754a 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone-redundant-branch-condition.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-redundant-branch-condition.rst @@ -83,6 +83,8 @@ Known limitations The ``else`` branch is not checked currently for negated condition variable: +.. code-block:: c + bool onFire = isBurning(); if (onFire) { scream(); diff --git a/clang/docs/Block-ABI-Apple.rst b/clang/docs/Block-ABI-Apple.rst index d038cdfe9bd20..e21a8b68b5cd1 100644 --- a/clang/docs/Block-ABI-Apple.rst +++ b/clang/docs/Block-ABI-Apple.rst @@ -35,7 +35,8 @@ High Level ========== The ABI of ``Blocks`` consist of their layout and the runtime functions required -by the compiler. A ``Block`` consists of a structure of the following form: +by the compiler. A ``Block`` of type ``R (^)(P...)`` consists of a structure of +the following form: .. code-block:: c @@ -43,7 +44,7 @@ by the compiler. A ``Block`` consists of a structure of the following form: void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock int flags; int reserved; - void (*invoke)(void *, ...); + R (*invoke)(struct Block_literal_1 *, P...); struct Block_descriptor_1 { unsigned long int reserved; // NULL unsigned long int size; // sizeof(struct Block_literal_1) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index c35718b51248c..72a25032151ff 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -758,7 +758,24 @@ the configuration (without a prefix: ``Auto``). int bbbbbbbbbbbbbbbbbbbbb) { } +**AttributeMacros** (``std::vector``) + A vector of strings that should be interpreted as attributes/qualifiers + instead of identifiers. This can be useful for language extensions or + static analyzer annotations: + .. code-block:: c++ + + x = (char *__capability)&y; + int function(void) __ununsed; + void only_writes_to_buffer(char *__output buffer); + + In the .clang-format configuration file, this can be configured like: + + .. code-block:: yaml + + AttributeMacros: ['__capability', '__output', '__ununsed'] + + For example: __capability. **BinPackArguments** (``bool``) If ``false``, a function call's arguments will either be all on the diff --git a/clang/docs/ThreadSafetyAnalysis.rst b/clang/docs/ThreadSafetyAnalysis.rst index ea8e98a1884bf..e4a3342c02bd8 100644 --- a/clang/docs/ThreadSafetyAnalysis.rst +++ b/clang/docs/ThreadSafetyAnalysis.rst @@ -209,21 +209,21 @@ must be held on entry to the function, *and must still be held on exit*. } -ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...) --------------------------------------------------------------------- +ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...), RELEASE_GENERIC(...) +------------------------------------------------------------------------------------------ *Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``, ``UNLOCK_FUNCTION`` -``ACQUIRE`` is an attribute on functions or methods, which -declares that the function acquires a capability, but does not release it. The -caller must not hold the given capability on entry, and it will hold the -capability on exit. ``ACQUIRE_SHARED`` is similar. +``ACQUIRE`` and ``ACQUIRE_SHARED`` are attributes on functions or methods +declaring that the function acquires a capability, but does not release it. +The given capability must not be held on entry, and will be held on exit +(exclusively for ``ACQUIRE``, shared for ``ACQUIRE_SHARED``). -``RELEASE`` and ``RELEASE_SHARED`` declare that the function releases the given -capability. The caller must hold the capability on entry, and will no longer -hold it on exit. It does not matter whether the given capability is shared or -exclusive. +``RELEASE``, ``RELEASE_SHARED``, and ``RELEASE_GENERIC`` declare that the +function releases the given capability. The capability must be held on entry +(exclusively for ``RELEASE``, shared for ``RELEASE_SHARED``, exclusively or +shared for ``RELEASE_GENERIC``), and will no longer be held on exit. .. code-block:: c++ @@ -402,6 +402,13 @@ the destructor. Such classes require special handling because the constructor and destructor refer to the capability via different names; see the ``MutexLocker`` class in :ref:`mutexheader`, below. +Scoped capabilities are treated as capabilities that are implicitly acquired +on construction and released on destruction. They are associated with +the set of (regular) capabilities named in thread safety attributes on the +constructor. Acquire-type attributes on other member functions are treated as +applying to that set of associated capabilities, while ``RELEASE`` implies that +a function releases all associated capabilities in whatever mode they're held. + TRY_ACQUIRE(, ...), TRY_ACQUIRE_SHARED(, ...) --------------------------------------------------------- @@ -414,6 +421,26 @@ The first argument must be ``true`` or ``false``, to specify which return value indicates success, and the remaining arguments are interpreted in the same way as ``ACQUIRE``. See :ref:`mutexheader`, below, for example uses. +Because the analysis doesn't support conditional locking, a capability is +treated as acquired after the first branch on the return value of a try-acquire +function. + +.. code-block:: c++ + + Mutex mu; + int a GUARDED_BY(mu); + + void foo() { + bool success = mu.TryLock(); + a = 0; // Warning, mu is not locked. + if (success) { + a = 0; // Ok. + mu.Unlock(); + } else { + a = 0; // Warning, mu is not locked. + } + } + ASSERT_CAPABILITY(...) and ASSERT_SHARED_CAPABILITY(...) -------------------------------------------------------- @@ -800,6 +827,9 @@ implementation. #define RELEASE_SHARED(...) \ THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) + #define RELEASE_GENERIC(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(__VA_ARGS__)) + #define TRY_ACQUIRE(...) \ THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) @@ -844,6 +874,9 @@ implementation. // Release/unlock a shared mutex. void ReaderUnlock() RELEASE_SHARED(); + // Generic unlock, can unlock exclusive and shared mutexes. + void GenericUnlock() RELEASE_GENERIC(); + // Try to acquire the mutex. Returns true on success, and false on failure. bool TryLock() TRY_ACQUIRE(true); @@ -860,19 +893,78 @@ implementation. const Mutex& operator!() const { return *this; } }; + // Tag types for selecting a constructor. + struct adopt_lock_t {} inline constexpr adopt_lock = {}; + struct defer_lock_t {} inline constexpr defer_lock = {}; + struct shared_lock_t {} inline constexpr shared_lock = {}; // MutexLocker is an RAII class that acquires a mutex in its constructor, and // releases it in its destructor. class SCOPED_CAPABILITY MutexLocker { private: Mutex* mut; + bool locked; public: - MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) { + // Acquire mu, implicitly acquire *this and associate it with mu. + MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu), locked(true) { mu->Lock(); } + + // Assume mu is held, implicitly acquire *this and associate it with mu. + MutexLocker(Mutex *mu, adopt_lock_t) REQUIRES(mu) : mut(mu), locked(true) {} + + // Acquire mu in shared mode, implicitly acquire *this and associate it with mu. + MutexLocker(Mutex *mu, shared_lock_t) ACQUIRE_SHARED(mu) : mut(mu), locked(true) { + mu->ReaderLock(); + } + + // Assume mu is held in shared mode, implicitly acquire *this and associate it with mu. + MutexLocker(Mutex *mu, adopt_lock_t, shared_lock_t) REQUIRES_SHARED(mu) + : mut(mu), locked(true) {} + + // Assume mu is not held, implicitly acquire *this and associate it with mu. + MutexLocker(Mutex *mu, defer_lock_t) EXCLUDES(mu) : mut(mu), locked(false) {} + + // Release *this and all associated mutexes, if they are still held. + // There is no warning if the scope was already unlocked before. ~MutexLocker() RELEASE() { + if (locked) + mut->GenericUnlock(); + } + + // Acquire all associated mutexes exclusively. + void Lock() ACQUIRE() { + mut->Lock(); + locked = true; + } + + // Try to acquire all associated mutexes exclusively. + bool TryLock() TRY_ACQUIRE(true) { + return locked = mut->TryLock(); + } + + // Acquire all associated mutexes in shared mode. + void ReaderLock() ACQUIRE_SHARED() { + mut->ReaderLock(); + locked = true; + } + + // Try to acquire all associated mutexes in shared mode. + bool ReaderTryLock() TRY_ACQUIRE_SHARED(true) { + return locked = mut->ReaderTryLock(); + } + + // Release all associated mutexes. Warn on double unlock. + void Unlock() RELEASE() { mut->Unlock(); + locked = false; + } + + // Release all associated mutexes. Warn on double unlock. + void ReaderUnlock() RELEASE() { + mut->ReaderUnlock(); + locked = false; } }; diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 3b378f735ebcc..7a294f916bcf9 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1747,7 +1747,7 @@ Check for integer to enumeration casts that could result in undefined values. void foo() { TestEnum t = static_cast(-1); // warn: the value provided to the cast expression is not in - the valid range of values for the enum + // the valid range of values for the enum .. _alpha-cplusplus-InvalidatedIterator: diff --git a/clang/examples/Attribute/CMakeLists.txt b/clang/examples/Attribute/CMakeLists.txt index ed02f5e5992f5..42f04f5039bc7 100644 --- a/clang/examples/Attribute/CMakeLists.txt +++ b/clang/examples/Attribute/CMakeLists.txt @@ -1,7 +1,7 @@ add_llvm_library(Attribute MODULE Attribute.cpp PLUGIN_TOOL clang) if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) - target_link_libraries(Attribute ${cmake_2_8_12_PRIVATE} + target_link_libraries(Attribute PRIVATE clangAST clangBasic clangFrontend diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index e0a998ac20a9c..bec6af48b941c 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2940,6 +2940,26 @@ CINDEX_LINKAGE int clang_getCursorPlatformAvailability( CINDEX_LINKAGE void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability); +/** + * If cursor refers to a variable declaration and it has initializer returns + * cursor referring to the initializer otherwise return null cursor. + */ +CINDEX_LINKAGE CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor); + +/** + * If cursor refers to a variable declaration that has global storage returns 1. + * If cursor refers to a variable declaration that doesn't have global storage + * returns 0. Otherwise returns -1. + */ +CINDEX_LINKAGE int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor); + +/** + * If cursor refers to a variable declaration that has external storage + * returns 1. If cursor refers to a variable declaration that doesn't have + * external storage returns 0. Otherwise returns -1. + */ +CINDEX_LINKAGE int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor); + /** * Describe the "language" of the entity referred to by a cursor. */ diff --git a/clang/include/clang-c/Rewrite.h b/clang/include/clang-c/Rewrite.h new file mode 100644 index 0000000000000..ce1b05594b384 --- /dev/null +++ b/clang/include/clang-c/Rewrite.h @@ -0,0 +1,63 @@ +/*===-- clang-c/Rewrite.h - C CXRewriter --------------------------*- C -*-===*\ +|* *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| +|* *| +|*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_CLANG_C_REWRITE_H +#define LLVM_CLANG_C_REWRITE_H + +#include "clang-c/CXString.h" +#include "clang-c/ExternC.h" +#include "clang-c/Index.h" +#include "clang-c/Platform.h" + +LLVM_CLANG_C_EXTERN_C_BEGIN + +typedef void *CXRewriter; + +/** + * Create CXRewriter. + */ +CINDEX_LINKAGE CXRewriter clang_CXRewriter_create(CXTranslationUnit TU); + +/** + * Insert the specified string at the specified location in the original buffer. + */ +CINDEX_LINKAGE void clang_CXRewriter_insertTextBefore(CXRewriter Rew, CXSourceLocation Loc, + const char *Insert); + +/** + * Replace the specified range of characters in the input with the specified + * replacement. + */ +CINDEX_LINKAGE void clang_CXRewriter_replaceText(CXRewriter Rew, CXSourceRange ToBeReplaced, + const char *Replacement); + +/** + * Remove the specified range. + */ +CINDEX_LINKAGE void clang_CXRewriter_removeText(CXRewriter Rew, CXSourceRange ToBeRemoved); + +/** + * Save all changed files to disk. + * Returns 1 if any files were not saved successfully, returns 0 otherwise. + */ +CINDEX_LINKAGE int clang_CXRewriter_overwriteChangedFiles(CXRewriter Rew); + +/** + * Write out rewritten version of the main file to stdout. + */ +CINDEX_LINKAGE void clang_CXRewriter_writeMainFileToStdOut(CXRewriter Rew); + +/** + * Free the given CXRewriter. + */ +CINDEX_LINKAGE void clang_CXRewriter_dispose(CXRewriter Rew); + +LLVM_CLANG_C_EXTERN_C_END + +#endif diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 87e4bd7f84c11..5103cfa8604e5 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -304,7 +304,7 @@ class APValue { MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); } APValue(const APValue &RHS); - APValue(APValue &&RHS) : Kind(None) { swap(RHS); } + APValue(APValue &&RHS); APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr = false) : Kind(None) { @@ -339,6 +339,9 @@ class APValue { return Result; } + APValue &operator=(const APValue &RHS); + APValue &operator=(APValue &&RHS); + ~APValue() { if (Kind != None && Kind != Indeterminate) DestroyDataAndMakeUninit(); @@ -591,12 +594,6 @@ class APValue { ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr; } - /// Assign by swapping from a copy of the RHS. - APValue &operator=(APValue RHS) { - swap(RHS); - return *this; - } - private: void DestroyDataAndMakeUninit(); void MakeInt() { diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 4feb1d45251d5..9e22543761501 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -77,7 +77,7 @@ class TemplateParameterList final /// The number of template parameters in this template /// parameter list. - unsigned NumParams : 30; + unsigned NumParams : 29; /// Whether this template parameter list contains an unexpanded parameter /// pack. diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 5edca25937896..26e52ad367f81 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -867,9 +867,9 @@ class Expr : public ValueStmt { /// Skip conversion operators. If this Expr is a call to a conversion /// operator, return the argument. - Expr *IgnoreConversionOperator() LLVM_READONLY; - const Expr *IgnoreConversionOperator() const { - return const_cast(this)->IgnoreConversionOperator(); + Expr *IgnoreConversionOperatorSingleStep() LLVM_READONLY; + const Expr *IgnoreConversionOperatorSingleStep() const { + return const_cast(this)->IgnoreConversionOperatorSingleStep(); } /// Skip past any parentheses and lvalue casts which might surround this @@ -901,9 +901,9 @@ class Expr : public ValueStmt { /// * What IgnoreParens() skips /// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase, /// CK_UncheckedDerivedToBase and CK_NoOp) - Expr *ignoreParenBaseCasts() LLVM_READONLY; - const Expr *ignoreParenBaseCasts() const { - return const_cast(this)->ignoreParenBaseCasts(); + Expr *IgnoreParenBaseCasts() LLVM_READONLY; + const Expr *IgnoreParenBaseCasts() const { + return const_cast(this)->IgnoreParenBaseCasts(); } /// Determine whether this expression is a default function argument. diff --git a/clang/include/clang/AST/IgnoreExpr.h b/clang/include/clang/AST/IgnoreExpr.h new file mode 100644 index 0000000000000..15d31f3af9954 --- /dev/null +++ b/clang/include/clang/AST/IgnoreExpr.h @@ -0,0 +1,61 @@ +//===--- IgnoreExpr.h - Ignore intermediate Expressions -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines common functions to ignore intermediate expression nodes +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_IGNOREEXPR_H +#define LLVM_CLANG_AST_IGNOREEXPR_H + +#include "clang/AST/Expr.h" + +namespace clang { +namespace detail { +/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, +/// Return Fn_n(...(Fn_1(E))) +inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; }; +template +Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) { + return IgnoreExprNodesImpl(Fn(E), std::forward(Fns)...); +} +} // namespace detail + +/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, +/// Recursively apply each of the functions to E until reaching a fixed point. +/// Note that a null E is valid; in this case nothing is done. +template Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) { + Expr *LastE = nullptr; + while (E != LastE) { + LastE = E; + E = detail::IgnoreExprNodesImpl(E, std::forward(Fns)...); + } + return E; +} + +Expr *IgnoreImplicitCastsSingleStep(Expr *E); + +Expr *IgnoreImplicitCastsExtraSingleStep(Expr *E); + +Expr *IgnoreCastsSingleStep(Expr *E); + +Expr *IgnoreLValueCastsSingleStep(Expr *E); + +Expr *IgnoreBaseCastsSingleStep(Expr *E); + +Expr *IgnoreImplicitSingleStep(Expr *E); + +Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E); + +Expr *IgnoreParensOnlySingleStep(Expr *E); + +Expr *IgnoreParensSingleStep(Expr *E); + +} // namespace clang + +#endif // LLVM_CLANG_AST_IGNOREEXPR_H diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 6e1d15bed74e6..ce58dff5833fd 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1198,6 +1198,14 @@ def SYCLIntelBufferLocation : InheritableAttr { let Documentation = [Undocumented]; } +def SYCLRequiresDecomposition : InheritableAttr { + // No spellings, as this is for internal use. + let Spellings = []; + let Subjects = SubjectList<[Named]>; + let LangOpts = [SYCLIsDevice, SYCLIsHost]; + let Documentation = [Undocumented]; +} + def SYCLIntelKernelArgsRestrict : InheritableAttr { let Spellings = [ CXX11<"intel", "kernel_args_restrict"> ]; let Subjects = SubjectList<[Function], ErrorDiag>; @@ -1209,7 +1217,7 @@ def SYCLIntelKernelArgsRestrict : InheritableAttr { def SYCLIntelNumSimdWorkItems : InheritableAttr { let Spellings = [CXX11<"intelfpga","num_simd_work_items">]; - let Args = [UnsignedArgument<"Number">]; + let Args = [ExprArgument<"Value">]; let LangOpts = [SYCLIsDevice, SYCLIsHost]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [SYCLIntelNumSimdWorkItemsAttrDocs]; @@ -1300,7 +1308,7 @@ def LoopUnrollHint : InheritableAttr { def IntelReqdSubGroupSize: InheritableAttr { let Spellings = [GNU<"intel_reqd_sub_group_size">, CXX11<"intel", "reqd_sub_group_size">]; - let Args = [ExprArgument<"SubGroupSize">]; + let Args = [ExprArgument<"Value">]; let Subjects = SubjectList<[Function, CXXMethod], ErrorDiag>; let Documentation = [IntelReqdSubGroupSizeDocs]; let LangOpts = [OpenCL, SYCLIsDevice, SYCLIsHost]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index fac9245c7a3d5..f9bb41bf0635a 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5407,10 +5407,6 @@ to the SVE predicate type ``svbool_t``, this excludes tuple types such as ``N==__ARM_FEATURE_SVE_BITS``, the implementation defined feature macro that is enabled under the ``-msve-vector-bits`` flag. -NOTE: This feature is currently WIP, the ``-msve-vector-bits=`` flag defines -the ``__ARM_FEATURE_SVE_BITS_EXPERIMENTAL`` macro. This feature is complete -when experimental is dropped. - For more information See `Arm C Language Extensions for SVE `_ for more information. }]; diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index b9824588939b2..89dd03075b28f 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -100,6 +100,11 @@ BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "") BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "") BUILTIN(__builtin_altivec_vmulouw, "V2ULLiV4UiV4Ui", "") BUILTIN(__builtin_altivec_vmulosw, "V2SLLiV4SiV4Si", "") +BUILTIN(__builtin_altivec_vmuleud, "V1ULLLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_vmulesd, "V1SLLLiV2SLLiV2SLLi", "") +BUILTIN(__builtin_altivec_vmuloud, "V1ULLLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_vmulosd, "V1SLLLiV2SLLiV2SLLi", "") +BUILTIN(__builtin_altivec_vmsumcud, "V1ULLLiV2ULLiV2ULLiV1ULLLi", "") BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "") @@ -317,6 +322,13 @@ BUILTIN(__builtin_altivec_vmulhuw, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_altivec_vmulhsd, "V2LLiV2LLiV2LLi", "") BUILTIN(__builtin_altivec_vmulhud, "V2ULLiV2ULLiV2ULLi", "") +// P10 Vector Expand with Mask built-ins. +BUILTIN(__builtin_altivec_vexpandbm, "V16UcV16Uc", "") +BUILTIN(__builtin_altivec_vexpandhm, "V8UsV8Us", "") +BUILTIN(__builtin_altivec_vexpandwm, "V4UiV4Ui", "") +BUILTIN(__builtin_altivec_vexpanddm, "V2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_vexpandqm, "V1ULLLiV1ULLLi", "") + // P10 Vector Parallel Bits built-ins. BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "") diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 758dfbc1d283d..ec77f68062e7a 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -14,20 +14,17 @@ // //===----------------------------------------------------------------------===// #ifndef CODEGENOPT -#error Define the CODEGENOPT macro to handle language options +# error Define the CODEGENOPT macro to handle language options #endif #ifndef VALUE_CODEGENOPT -#define VALUE_CODEGENOPT(Name, Bits, Default) CODEGENOPT(Name, Bits, Default) +# define VALUE_CODEGENOPT(Name, Bits, Default) \ +CODEGENOPT(Name, Bits, Default) #endif #ifndef ENUM_CODEGENOPT -#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ - CODEGENOPT(Name, Bits, Default) -#endif - -#ifndef TYPED_CODEGENOPT -#define TYPED_CODEGENOPT(Type, Name, Description) +# define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ +CODEGENOPT(Name, Bits, Default) #endif CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as @@ -148,7 +145,7 @@ CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can ///< linker. CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants. CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled. -CODEGENOPT(HeapProf , 1, 0) ///< Set when -fmemprof is enabled. +CODEGENOPT(HeapProf , 1, 0) ///< Set when -fmemory-profile is enabled. CODEGENOPT(MSVolatile , 1, 0) ///< Set when /volatile:ms is enabled. CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled. CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is @@ -398,226 +395,6 @@ CODEGENOPT(KeepStaticConsts, 1, 0) /// Whether to not follow the AAPCS that enforce at least one read before storing to a volatile bitfield CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0) -TYPED_CODEGENOPT( - std::string, BBSections, - "This field stores one of the allowed values for the option " - "-fbasic-block-sections=. The allowed values with this option are: " - "{\"labels\", \"all\", \"list=\", \"none\"}. \"labels\": Only " - "generate basic block symbols (labels) for all basic blocks, do not " - "generate unique sections for basic blocks. Use the machine basic block id " - "in the symbol name to associate profile info from virtual address to " - "machine basic block. \"all\" : Generate basic block sections for " - "all basic blocks. \"list=\": Generate basic block sections for a " - "subset of basic blocks. The functions and the machine basic block ids are " - "specified in the file. \"none\": Disable sections/labels for basic " - "blocks.") - -TYPED_CODEGENOPT(std::string, CodeModel, "The code model to use (-mcmodel).") - -TYPED_CODEGENOPT(std::string, CoverageDataFile, - "The filename with path we use for coverage data files. The " - "runtime allows further manipulation with the GCOV_PREFIX and " - "GCOV_PREFIX_STRIP environment variables. The filename with " - "path we use for coverage notes files.") -TYPED_CODEGENOPT(std::string, CoverageNotesFile, "") - -TYPED_CODEGENOPT( - std::string, ProfileFilterFiles, - "Regexes separated by a semi-colon to filter the files to instrument.") - -TYPED_CODEGENOPT( - std::string, ProfileExcludeFiles, - "Regexes separated by a semi-colon to filter the files to not instrument.") - -TYPED_CODEGENOPT(CoverageVersionTy, CoverageVersion, - "The version string to put into coverage files.") - -TYPED_CODEGENOPT(std::string, DebugPass, - "Enable additional debugging information.") - -TYPED_CODEGENOPT(std::string, DebugCompilationDir, - "The string to embed in debug information as the current " - "working directory.") - -TYPED_CODEGENOPT(std::string, DwarfDebugFlags, - "The string to embed in the debug information for the compile " - "unit, if non-empty.") - -TYPED_CODEGENOPT(std::string, RecordCommandLine, - "The string containing the commandline for the " - "llvm.commandline metadata, if non-empty.") - -TYPED_CODEGENOPT(DebugPrefixMapTy, DebugPrefixMap, "") - -TYPED_CODEGENOPT(std::string, FloatABI, - "The ABI to use for passing floating point arguments.") - -TYPED_CODEGENOPT(llvm::DenormalMode, FPDenormalMode, - "The floating-point denormal mode to use.") - -TYPED_CODEGENOPT(llvm::DenormalMode, FP32DenormalMode, - "The floating-point denormal mode to use, for float.") - -TYPED_CODEGENOPT(std::string, LimitFloatPrecision, - "The float precision limit to use, if non-empty.") - -TYPED_CODEGENOPT(std::vector, LinkBitcodeFiles, - "The files specified here are linked in to the module before " - "optimizations.") - -TYPED_CODEGENOPT( - std::string, MainFileName, - "The user provided name for the \"main file\", if non-empty. This is " - "useful in situations where the input file name does not match the " - "original input file, for example with -save-temps.") - -TYPED_CODEGENOPT(std::string, SplitDwarfFile, - "The name for the split debug info file used for the " - "DW_AT_[GNU_]dwo_name attribute in the skeleton CU.") - -TYPED_CODEGENOPT( - std::string, SplitDwarfOutput, - "Output filename for the split debug info, not used in the skeleton CU.") - -TYPED_CODEGENOPT(llvm::Reloc::Model, RelocationModel, - "The name of the relocation model to use.") - -TYPED_CODEGENOPT(std::string, ThreadModel, "The thread model to use") - -TYPED_CODEGENOPT(std::string, TrapFuncName, - "If not an empty string, trap intrinsics are lowered to calls " - "to this function instead of to trap instructions.") - -TYPED_CODEGENOPT(std::vector, DependentLibraries, - "A list of dependent libraries.") - -TYPED_CODEGENOPT(std::vector, LinkerOptions, - "A list of linker options to embed in the object file.") - -TYPED_CODEGENOPT( - std::string, InstrProfileOutput, - "Name of the profile file to use as output for -fprofile-instr-generate, " - "-fprofile-generate, and -fcs-profile-generate.") - -TYPED_CODEGENOPT(std::string, SampleProfileFile, - "Name of the profile file to use with -fprofile-sample-use.") - -TYPED_CODEGENOPT( - std::string, ProfileInstrumentUsePath, - "Name of the profile file to use as input for -fprofile-instr-use") - -TYPED_CODEGENOPT( - std::string, ProfileRemappingFile, - "Name of the profile remapping file to apply to the profile data supplied " - "by -fprofile-sample-use or -fprofile-instr-use.") - -TYPED_CODEGENOPT(std::string, ThinLTOIndexFile, - "Name of the function summary index file to use for ThinLTO " - "function importing.") - -TYPED_CODEGENOPT( - std::string, ThinLinkBitcodeFile, - "Name of a file that can optionally be written with minimized bitcode to " - "be used as input for the ThinLTO thin link step, which only needs the " - "summary and module symbol table (and not, e.g. any debug metadata).") - -TYPED_CODEGENOPT(std::string, SaveTempsFilePrefix, - "Prefix to use for -save-temps output.") - -TYPED_CODEGENOPT( - std::string, CudaGpuBinaryFileName, - "Name of file passed with -fcuda-include-gpubinary option to forward to " - "CUDA runtime back-end for incorporating them into host-side object file.") - -TYPED_CODEGENOPT(std::string, OptRecordFile, - "The name of the file to which the backend should save YAML " - "optimization records.") - -TYPED_CODEGENOPT(std::string, OptRecordPasses, - "The regex that filters the passes that should be saved to " - "the optimization records.") - -TYPED_CODEGENOPT(std::string, OptRecordFormat, - "The format used for serializing remarks (default: YAML)") - -TYPED_CODEGENOPT( - std::string, SymbolPartition, - "The name of the partition that symbols are assigned to, specified with " - "-fsymbol-partition (see https://lld.llvm.org/Partitions.html).") - -TYPED_CODEGENOPT( - std::shared_ptr, OptimizationRemarkPattern, - "Regular expression to select optimizations for which we should enable " - "optimization remarks. Transformation passes whose name matches this " - "expression (and support this feature), will emit a diagnostic whenever " - "they perform a transformation. This is enabled by the -Rpass=regexp flag.") - -TYPED_CODEGENOPT( - std::shared_ptr, OptimizationRemarkMissedPattern, - "Regular expression to select optimizations for which we should enable " - "missed optimization remarks. Transformation passes whose name matches " - "this expression (and support this feature), will emit a diagnostic " - "whenever they tried but failed to perform a transformation. This is " - "enabled by the -Rpass-missed=regexp flag.") - -TYPED_CODEGENOPT( - std::shared_ptr, OptimizationRemarkAnalysisPattern, - "Regular expression to select optimizations for which we should enable " - "optimization analyses. Transformation passes whose name matches this " - "expression (and support this feature), will emit a diagnostic whenever " - "they want to explain why they decided to apply or not apply a given " - "transformation. This is enabled by the -Rpass-analysis=regexp flag.") - -TYPED_CODEGENOPT(std::vector, RewriteMapFiles, - "Set of files defining the rules for the symbol rewriting.") - -TYPED_CODEGENOPT(SanitizerSet, SanitizeRecover, - "Set of sanitizer checks that are non-fatal (i.e. execution " - "should be continued when possible).") - -TYPED_CODEGENOPT(SanitizerSet, SanitizeTrap, - "Set of sanitizer checks that trap rather than diagnose.") - -TYPED_CODEGENOPT(std::vector, CmdArgs, - "List of backend command-line options for -fembed-bitcode.") - -TYPED_CODEGENOPT(std::vector, NoBuiltinFuncs, - "A list of all -fno-builtin-* function names (e.g., memset).") - -TYPED_CODEGENOPT(std::vector, Reciprocals, "") - -TYPED_CODEGENOPT(std::string, PreferVectorWidth, - "The preferred width for auto-vectorization transforms. This " - "is intended to override default transforms based on the " - "width of the architected vector registers.") - -TYPED_CODEGENOPT(XRayInstrSet, XRayInstrumentationBundle, - "Set of XRay instrumentation kinds to emit.") - -TYPED_CODEGENOPT(std::vector, DefaultFunctionAttrs, "") - -TYPED_CODEGENOPT( - std::vector, PassPlugins, - "List of dynamic shared object files to be loaded as pass plugins.") - -TYPED_CODEGENOPT( - std::vector, SanitizeCoverageAllowlistFiles, - "Path to allowlist file specifying which objects (files, functions) should " - "exclusively be instrumented by sanitizer coverage pass.") - -TYPED_CODEGENOPT(std::vector, SanitizeCoverageBlocklistFiles, - "Path to blocklist file specifying which objects (files, " - "functions) listed for instrumentation by sanitizer coverage " - "pass should actually not be instrumented.") - -TYPED_CODEGENOPT( - const char *, Argv0, - "Executable and command-line used to create a given CompilerInvocation. " - "Most of the time this will be the full -cc1 command.") - -TYPED_CODEGENOPT(ArrayRef, CommandLineArgs, "") - #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT -#undef TYPED_CODEGENOPT diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 093f4014ae8c3..ca391bf8f1861 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -110,15 +110,75 @@ class CodeGenOptions : public CodeGenOptionsBase { Embed_Marker // Embed a marker as a placeholder for bitcode. }; + // This field stores one of the allowed values for the option + // -fbasic-block-sections=. The allowed values with this option are: + // {"labels", "all", "list=", "none"}. + // + // "labels": Only generate basic block symbols (labels) for all basic + // blocks, do not generate unique sections for basic blocks. + // Use the machine basic block id in the symbol name to + // associate profile info from virtual address to machine + // basic block. + // "all" : Generate basic block sections for all basic blocks. + // "list=": Generate basic block sections for a subset of basic blocks. + // The functions and the machine basic block ids are specified + // in the file. + // "none": Disable sections/labels for basic blocks. + std::string BBSections; + enum class FramePointerKind { None, // Omit all frame pointers. NonLeaf, // Keep non-leaf frame pointers. All, // Keep all frame pointers. }; - using DebugPrefixMapTy = std::map; + /// The code model to use (-mcmodel). + std::string CodeModel; + + /// The filename with path we use for coverage data files. The runtime + /// allows further manipulation with the GCOV_PREFIX and GCOV_PREFIX_STRIP + /// environment variables. + std::string CoverageDataFile; + + /// The filename with path we use for coverage notes files. + std::string CoverageNotesFile; + + /// Regexes separated by a semi-colon to filter the files to instrument. + std::string ProfileFilterFiles; + + /// Regexes separated by a semi-colon to filter the files to not instrument. + std::string ProfileExcludeFiles; + + /// The version string to put into coverage files. + char CoverageVersion[4]; + + /// Enable additional debugging information. + std::string DebugPass; + + /// The string to embed in debug information as the current working directory. + std::string DebugCompilationDir; + + /// The string to embed in the debug information for the compile unit, if + /// non-empty. + std::string DwarfDebugFlags; + + /// The string containing the commandline for the llvm.commandline metadata, + /// if non-empty. + std::string RecordCommandLine; + + std::map DebugPrefixMap; + + /// The ABI to use for passing floating point arguments. + std::string FloatABI; + + /// The floating-point denormal mode to use. + llvm::DenormalMode FPDenormalMode = llvm::DenormalMode::getIEEE(); - using CoverageVersionTy = char[4]; + /// The floating-point denormal mode to use, for float. + llvm::DenormalMode FP32DenormalMode = llvm::DenormalMode::getIEEE(); + + /// The float precision limit to use, if non-empty. + std::string LimitFloatPrecision; struct BitcodeFileToLink { /// The filename of the bitcode file to link in. @@ -133,14 +193,156 @@ class CodeGenOptions : public CodeGenOptionsBase { unsigned LinkFlags = 0; }; + /// The files specified here are linked in to the module before optimizations. + std::vector LinkBitcodeFiles; + + /// The user provided name for the "main file", if non-empty. This is useful + /// in situations where the input file name does not match the original input + /// file, for example with -save-temps. + std::string MainFileName; + + /// The name for the split debug info file used for the DW_AT_[GNU_]dwo_name + /// attribute in the skeleton CU. + std::string SplitDwarfFile; + + /// Output filename for the split debug info, not used in the skeleton CU. + std::string SplitDwarfOutput; + + /// The name of the relocation model to use. + llvm::Reloc::Model RelocationModel; + + /// The thread model to use + std::string ThreadModel; + + /// If not an empty string, trap intrinsics are lowered to calls to this + /// function instead of to trap instructions. + std::string TrapFuncName; + + /// A list of dependent libraries. + std::vector DependentLibraries; + + /// A list of linker options to embed in the object file. + std::vector LinkerOptions; + + /// Name of the profile file to use as output for -fprofile-instr-generate, + /// -fprofile-generate, and -fcs-profile-generate. + std::string InstrProfileOutput; + + /// Name of the profile file to use with -fprofile-sample-use. + std::string SampleProfileFile; + + /// Name of the profile file to use as input for -fprofile-instr-use + std::string ProfileInstrumentUsePath; + + /// Name of the profile remapping file to apply to the profile data supplied + /// by -fprofile-sample-use or -fprofile-instr-use. + std::string ProfileRemappingFile; + + /// Name of the function summary index file to use for ThinLTO function + /// importing. + std::string ThinLTOIndexFile; + + /// Name of a file that can optionally be written with minimized bitcode + /// to be used as input for the ThinLTO thin link step, which only needs + /// the summary and module symbol table (and not, e.g. any debug metadata). + std::string ThinLinkBitcodeFile; + + /// Prefix to use for -save-temps output. + std::string SaveTempsFilePrefix; + + /// Name of file passed with -fcuda-include-gpubinary option to forward to + /// CUDA runtime back-end for incorporating them into host-side object file. + std::string CudaGpuBinaryFileName; + + /// The name of the file to which the backend should save YAML optimization + /// records. + std::string OptRecordFile; + + /// The regex that filters the passes that should be saved to the optimization + /// records. + std::string OptRecordPasses; + + /// The format used for serializing remarks (default: YAML) + std::string OptRecordFormat; + + /// The name of the partition that symbols are assigned to, specified with + /// -fsymbol-partition (see https://lld.llvm.org/Partitions.html). + std::string SymbolPartition; + + /// Regular expression to select optimizations for which we should enable + /// optimization remarks. Transformation passes whose name matches this + /// expression (and support this feature), will emit a diagnostic + /// whenever they perform a transformation. This is enabled by the + /// -Rpass=regexp flag. + std::shared_ptr OptimizationRemarkPattern; + + /// Regular expression to select optimizations for which we should enable + /// missed optimization remarks. Transformation passes whose name matches this + /// expression (and support this feature), will emit a diagnostic + /// whenever they tried but failed to perform a transformation. This is + /// enabled by the -Rpass-missed=regexp flag. + std::shared_ptr OptimizationRemarkMissedPattern; + + /// Regular expression to select optimizations for which we should enable + /// optimization analyses. Transformation passes whose name matches this + /// expression (and support this feature), will emit a diagnostic + /// whenever they want to explain why they decided to apply or not apply + /// a given transformation. This is enabled by the -Rpass-analysis=regexp + /// flag. + std::shared_ptr OptimizationRemarkAnalysisPattern; + + /// Set of files defining the rules for the symbol rewriting. + std::vector RewriteMapFiles; + + /// Set of sanitizer checks that are non-fatal (i.e. execution should be + /// continued when possible). + SanitizerSet SanitizeRecover; + + /// Set of sanitizer checks that trap rather than diagnose. + SanitizerSet SanitizeTrap; + + /// List of backend command-line options for -fembed-bitcode. + std::vector CmdArgs; + + /// A list of all -fno-builtin-* function names (e.g., memset). + std::vector NoBuiltinFuncs; + + std::vector Reciprocals; + + /// The preferred width for auto-vectorization transforms. This is intended to + /// override default transforms based on the width of the architected vector + /// registers. + std::string PreferVectorWidth; + + /// Set of XRay instrumentation kinds to emit. + XRayInstrSet XRayInstrumentationBundle; + + std::vector DefaultFunctionAttrs; + + /// List of dynamic shared object files to be loaded as pass plugins. + std::vector PassPlugins; + + /// Path to allowlist file specifying which objects + /// (files, functions) should exclusively be instrumented + /// by sanitizer coverage pass. + std::vector SanitizeCoverageAllowlistFiles; + + /// Path to blocklist file specifying which objects + /// (files, functions) listed for instrumentation by sanitizer + /// coverage pass should actually not be instrumented. + std::vector SanitizeCoverageBlocklistFiles; + + /// Executable and command-line used to create a given CompilerInvocation. + /// Most of the time this will be the full -cc1 command. + const char *Argv0 = nullptr; + ArrayRef CommandLineArgs; public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) -#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ - Type get##Name() const { return static_cast(Name); } \ +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ + Type get##Name() const { return static_cast(Name); } \ void set##Name(Type Value) { Name = static_cast(Value); } -#define TYPED_CODEGENOPT(Type, Name, Description) Type Name; #include "clang/Basic/CodeGenOptions.def" CodeGenOptions(); diff --git a/clang/include/clang/Basic/CommentOptions.def b/clang/include/clang/Basic/CommentOptions.def deleted file mode 100644 index 537f9eb34bd43..0000000000000 --- a/clang/include/clang/Basic/CommentOptions.def +++ /dev/null @@ -1,26 +0,0 @@ -//===--- CommentOptions.def - Comment option database -------------*- C++ -//-*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the comment options. Users of this file must -// define the TYPED_COMMENTOPT macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_COMMENTOPT -#define TYPED_COMMENTOPT(Type, Name, Description) -#endif - -TYPED_COMMENTOPT(BlockCommandNamesTy, BlockCommandNames, - "Command names to treat as vlock commands in comments. Should " - "not include the leading backslash.") - -TYPED_COMMENTOPT(bool, ParseAllComments, - "Treat ordinary comments as documentation comments") - -#undef TYPED_COMMENTOPT diff --git a/clang/include/clang/Basic/CommentOptions.h b/clang/include/clang/Basic/CommentOptions.h index 149650e6192a4..7d142fc32f511 100644 --- a/clang/include/clang/Basic/CommentOptions.h +++ b/clang/include/clang/Basic/CommentOptions.h @@ -23,10 +23,14 @@ namespace clang { struct CommentOptions { using BlockCommandNamesTy = std::vector; -#define TYPED_COMMENTOPT(Type, Name, Description) Type Name; -#include "clang/Basic/CommentOptions.def" + /// Command names to treat as block commands in comments. + /// Should not include the leading backslash. + BlockCommandNamesTy BlockCommandNames; - CommentOptions() : ParseAllComments(false) {} + /// Treat ordinary comments as documentation comments. + bool ParseAllComments = false; + + CommentOptions() = default; }; } // namespace clang diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index 9be75f3751198..6a9ff309e49cb 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -298,6 +298,8 @@ def note_constexpr_bit_cast_invalid_subtype : Note< def note_constexpr_bit_cast_indet_dest : Note< "indeterminate value can only initialize an object of type 'unsigned char'" "%select{, 'char',|}1 or 'std::byte'; %0 is invalid">; +def note_constexpr_bit_cast_unrepresentable_value : Note< + "value %1 cannot be represented in type %0">; def note_constexpr_pseudo_destructor : Note< "pseudo-destructor call is not permitted in constant expressions " "until C++20">; diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index d4e2fdf23a9e1..42e5f0699a419 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -132,6 +132,7 @@ def err_drv_invalid_Xsycl_frontend_with_args : Error< "invalid -Xsycl-target-frontend argument: '%0', options requiring arguments are unsupported">; def err_drv_bad_fpga_device_count : Error< "More than one FPGA specific device binary found in input objects">; +def err_drv_unsupported_opt_dpcpp : Error<"option '%0' unsupported with DPC++">; def err_drv_argument_only_allowed_with : Error< "invalid argument '%0' only allowed with '%1'">; def err_drv_argument_not_allowed_with : Error< @@ -273,7 +274,7 @@ def err_drv_expecting_fopenmp_with_fopenmp_targets : Error< def err_drv_expecting_fsycl_with_sycl_opt : Error< "The option %0 must be used in conjunction with -fsycl to enable offloading.">; def err_drv_fsycl_with_c_type : Error< - "The option %0%1 must not be used in conjunction with -fsycl which expects C++ source.">; + "The option '%0' must not be used in conjunction with '-fsycl', which expects C++ source.">; def warn_drv_omp_offload_target_duplicate : Warning< "The OpenMP offloading target '%0' is similar to target '%1' already specified - will be ignored.">, InGroup; diff --git a/clang/include/clang/Basic/DiagnosticOptions.def b/clang/include/clang/Basic/DiagnosticOptions.def index 35b01b8c5ce04..a946b5c6be8ef 100644 --- a/clang/include/clang/Basic/DiagnosticOptions.def +++ b/clang/include/clang/Basic/DiagnosticOptions.def @@ -43,10 +43,6 @@ DIAGOPT(Name, Bits, Default) ENUM_DIAGOPT(Name, Type, Bits, Default) #endif -#ifndef TYPED_DIAGOPT -#define TYPED_DIAGOPT(Type, Name, Description) -#endif - SEMANTIC_DIAGOPT(IgnoreWarnings, 1, 0) /// -w DIAGOPT(NoRewriteMacros, 1, 0) /// -Wno-rewrite-macros DIAGOPT(Pedantic, 1, 0) /// -pedantic @@ -99,32 +95,9 @@ VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops. /// Column limit for formatting message diagnostics, or 0 if unused. VALUE_DIAGOPT(MessageLength, 32, 0) -TYPED_DIAGOPT(std::string, DiagnosticLogFile, - "The file to log diagnostic output to.") - -TYPED_DIAGOPT(std::string, DiagnosticSerializationFile, - "The file to serialize diagnostics to (non-appending).") - -TYPED_DIAGOPT(std::vector, Warnings, - "The list of -W... options used to alter the diagnostic " - "mappings, with the prefixes removed.") - -TYPED_DIAGOPT(std::vector, UndefPrefixes, - "The list of prefixes from -Wundef-prefix=... used to generate " - "warnings for undefined macros.") - -TYPED_DIAGOPT(std::vector, Remarks, - "The list of -R... options used to alter the diagnostic " - "mappings, with the prefixes removed.") - -TYPED_DIAGOPT(std::vector, VerifyPrefixes, - "The prefixes for comment directives sought by -verify " - "(\"expected\" by /// default).") - #undef DIAGOPT #undef ENUM_DIAGOPT #undef VALUE_DIAGOPT #undef SEMANTIC_DIAGOPT #undef SEMANTIC_ENUM_DIAGOPT #undef SEMANTIC_VALUE_DIAGOPT -#undef TYPED_DIAGOPT diff --git a/clang/include/clang/Basic/DiagnosticOptions.h b/clang/include/clang/Basic/DiagnosticOptions.h index 2b6bd1fd2be57..7fbe534c5994b 100644 --- a/clang/include/clang/Basic/DiagnosticOptions.h +++ b/clang/include/clang/Basic/DiagnosticOptions.h @@ -88,9 +88,31 @@ class DiagnosticOptions : public RefCountedBase{ #include "clang/Basic/DiagnosticOptions.def" public: -#define TYPED_DIAGOPT(Type, Name, Description) Type Name; + /// The file to log diagnostic output to. + std::string DiagnosticLogFile; + + /// The file to serialize diagnostics to (non-appending). + std::string DiagnosticSerializationFile; + + /// The list of -W... options used to alter the diagnostic mappings, with the + /// prefixes removed. + std::vector Warnings; + + /// The list of prefixes from -Wundef-prefix=... used to generate warnings + /// for undefined macros. + std::vector UndefPrefixes; + + /// The list of -R... options used to alter the diagnostic mappings, with the + /// prefixes removed. + std::vector Remarks; + + /// The prefixes for comment directives sought by -verify ("expected" by + /// default). + std::vector VerifyPrefixes; + +public: + // Define accessors/mutators for diagnostic options of enumeration type. #define DIAGOPT(Name, Bits, Default) -// Define accessors/mutators for diagnostic options of enumeration type. #define ENUM_DIAGOPT(Name, Type, Bits, Default) \ Type get##Name() const { return static_cast(Name); } \ void set##Name(Type Value) { Name = static_cast(Value); } diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index c7b3031e0644e..57e6f398f3507 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1136,6 +1136,12 @@ def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">, def warn_stdc_fenv_access_not_supported : Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">, InGroup; +def warn_stdc_fenv_round_not_supported : + Warning<"pragma STDC FENV_ROUND is not supported">, + InGroup; +def warn_stdc_unknown_rounding_mode : Warning< + "invalid or unsupported rounding mode in '#pragma STDC FENV_ROUND' - ignored">, + InGroup; // - #pragma comment def err_pragma_comment_malformed : Error< "pragma comment requires parenthesized identifier and optional string">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5ce722fd67e12..eedd3cd677ccd 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10982,6 +10982,7 @@ def err_sycl_kernel_incorrectly_named : Error< "kernel %select{name is missing" "|needs to have a globally-visible name" "|name is invalid. Unscoped enum requires fixed underlying type" + "|name cannot be a type in the \"std\" namespace" "}0">; def err_sycl_kernel_not_function_object : Error<"kernel parameter must be a lambda or function object">; @@ -11003,8 +11004,8 @@ def err_sycl_restrict : Error< "nor constant-initialized" "}0">; def warn_sycl_kernel_too_big_args : Warning< - "size of kernel arguments (%0 bytes) exceeds supported maximum of %1 bytes " - "on GPU">, InGroup; + "size of kernel arguments (%0 bytes) may exceed the supported maximum " + "of %1 bytes on some devices">, InGroup; def err_sycl_virtual_types : Error< "No class with a vtable can be used in a SYCL kernel or any code included in the kernel">; def note_sycl_recursive_function_declared_here: Note<"function implemented using recursion declared here">; @@ -11036,9 +11037,10 @@ def err_sycl_compiletime_property_duplication : Error< def err_sycl_invalid_property_list_param_number : Error< "%0 must have exactly one template parameter">; def err_sycl_invalid_accessor_property_template_param : Error< - "Fifth template parameter of the accessor must be of a property_list type">; -def err_sycl_invalid_property_list_template_param : Error< - "%select{property_list|property_list pack argument|buffer_location}0 " + "sixth template parameter of the accessor must be of accessor_property_list " + "type">; +def err_sycl_invalid_accessor_property_list_template_param : Error< + "%select{accessor_property_list|accessor_property_list pack argument|buffer_location}0 " "template parameter must be a " "%select{parameter pack|type|non-negative integer}1">; def warn_sycl_pass_by_value_deprecated diff --git a/clang/include/clang/Basic/FileSystemOptions.def b/clang/include/clang/Basic/FileSystemOptions.def deleted file mode 100644 index 794e9871998e7..0000000000000 --- a/clang/include/clang/Basic/FileSystemOptions.def +++ /dev/null @@ -1,21 +0,0 @@ -//===--- FileSystemOptions.def - FileSystem option database -----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the FileSystem options. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_FILESYSTEMOPT -#error define TYPED_FILESYSTEMOPT macro to hand filesystem options -#endif - -TYPED_FILESYSTEMOPT(std::string, WorkingDir, - "If set, paths are resolved as if the working directory was set " - "to the value of WorkingDir.") - -#undef TYPED_FILESYSTEMOPT diff --git a/clang/include/clang/Basic/FileSystemOptions.h b/clang/include/clang/Basic/FileSystemOptions.h index 4fd0851145a2b..458af0c7b6592 100644 --- a/clang/include/clang/Basic/FileSystemOptions.h +++ b/clang/include/clang/Basic/FileSystemOptions.h @@ -21,8 +21,9 @@ namespace clang { /// Keeps track of options that affect how file operations are performed. class FileSystemOptions { public: -#define TYPED_FILESYSTEMOPT(Type, Name, Description) Type Name; -#include "clang/Basic/FileSystemOptions.def" + /// If set, paths are resolved as if the working directory was + /// set to the value of WorkingDir. + std::string WorkingDir; }; } // end namespace clang diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index ff431726e91d4..a54aab241df7f 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -78,10 +78,6 @@ COMPATIBLE_VALUE_LANGOPT(Name, Bits, Default, Description) #endif -#ifndef TYPED_LANGOPT -#define TYPED_LANGOPT(Type, Name, Descritpion) -#endif - // FIXME: A lot of the BENIGN_ options should be COMPATIBLE_ instead. LANGOPT(C99 , 1, 0, "C99") LANGOPT(C11 , 1, 0, "C11") @@ -244,7 +240,7 @@ LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr function LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions") LANGOPT(GPURelocatableDeviceCode, 1, 0, "generate relocatable device code") LANGOPT(GPUAllowDeviceInit, 1, 0, "allowing device side global init functions for HIP") -LANGOPT(GPUMaxThreadsPerBlock, 32, 1024, "default max threads per block for kernel launch bounds for HIP") +LANGOPT(GPUMaxThreadsPerBlock, 32, 256, "default max threads per block for kernel launch bounds for HIP") LANGOPT(SYCL , 1, 0, "SYCL") LANGOPT(SYCLIsDevice , 1, 0, "Generate code for SYCL device") @@ -277,6 +273,9 @@ BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd re BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables") LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings") BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden visibility for inline C++ methods") +BENIGN_LANGOPT(VisibilityInlinesHiddenStaticLocalVar, 1, 0, + "hidden visibility for static local variables in inline C++ " + "methods when -fvisibility-inlines hidden is enabled") LANGOPT(GlobalAllocationFunctionVisibilityHidden , 1, 0, "hidden visibility for global operator new and delete declaration") BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype") BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support") @@ -400,73 +399,6 @@ LANGOPT(RelativeCXXABIVTables, 1, 0, LANGOPT(ArmSveVectorBits, 32, 0, "SVE vector size in bits") -TYPED_LANGOPT(SanitizerSet, Sanitize, "Set of enabled sanitizers.") - -TYPED_LANGOPT(std::vector, SanitizerBlacklistFiles, - "Paths to blacklist files specifying which objects (files, " - "functions, variables) should not be instrumented.") - -TYPED_LANGOPT(std::vector, XRayAlwaysInstrumentFiles, - "Paths to the XRay \"always instrument\" files specifying which " - "objects (files, functions, variables) should be imbued with the " - "XRay \"always instrument\" attribute. WARNING: This is a " - "deprecated field and will go away in the future.") - -TYPED_LANGOPT(std::vector, XRayNeverInstrumentFiles, - "Paths to the XRay \"never instrument\" files specifying which " - "objects (files, functions, variables) should be imbued with the " - "XRay \"never instrument\" attribute. WARNING: This is a " - "deprecated field and will go away in the future.") - -TYPED_LANGOPT(std::vector, XRayAttrListFiles, - "Paths to the XRay attribute list files, specifying which " - "objects (files, functions, variables) should be imbued with the " - "appropriate XRay attribute(s).") - -TYPED_LANGOPT(clang::ObjCRuntime, ObjCRuntime, "") - -TYPED_LANGOPT(CoreFoundationABI, CFRuntime, "") - -TYPED_LANGOPT(std::string, ObjCConstantStringClass, "") - -TYPED_LANGOPT( - std::string, OverflowHandler, - "The name of the handler function to be called when -ftrapv is specified. " - "If none is specified, abort (GCC-compatible behaviour).") - -TYPED_LANGOPT( - std::string, ModuleName, - "The module currently being compiled as specified by -fmodule-name.") - -TYPED_LANGOPT( - std::string, CurrentModule, - "The name of the current module, of which the main source file is a part. " - "If CompilingModule is set, we are compiling the interface of this module, " - "otherwise we are compiling an implementation file of it. This starts as " - "ModuleName in case -fmodule-name is provided and changes during " - "compilation to reflect the current module.") - -TYPED_LANGOPT(std::vector, ModuleFeatures, - "The names of any features to enable in module 'requires' decls " - "in addition to the hard-coded list in Module.cpp and the target " - "features. This list is sorted.") - -TYPED_LANGOPT(std::vector, NoBuiltinFuncs, - "A list of all -fno-builtin-* function names (e.g., memset).") - -TYPED_LANGOPT( - std::vector, OMPTargetTriples, - "Triples of the OpenMP targets that the host code codegen should take into " - "account in order to generate accurate offloading descriptors.") - -TYPED_LANGOPT(std::string, OMPHostIRFile, - "Name of the IR file that contains the result of the OpenMP " - "target host code generation.") - -TYPED_LANGOPT(bool, IsHeaderFile, - "Indicates whether the front-end is explicitly told that the " - "input is a header file (i.e. -x c-header).") - #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT @@ -476,4 +408,3 @@ TYPED_LANGOPT(bool, IsHeaderFile, #undef VALUE_LANGOPT #undef COMPATIBLE_VALUE_LANGOPT #undef BENIGN_VALUE_LANGOPT -#undef TYPED_LANGOPT diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 110943fe63c03..9d51eb7ba597d 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -232,12 +232,75 @@ class LangOptions : public LangOptionsBase { }; public: + /// Set of enabled sanitizers. + SanitizerSet Sanitize; + + /// Paths to blacklist files specifying which objects + /// (files, functions, variables) should not be instrumented. + std::vector SanitizerBlacklistFiles; + + /// Paths to the XRay "always instrument" files specifying which + /// objects (files, functions, variables) should be imbued with the XRay + /// "always instrument" attribute. + /// WARNING: This is a deprecated field and will go away in the future. + std::vector XRayAlwaysInstrumentFiles; + + /// Paths to the XRay "never instrument" files specifying which + /// objects (files, functions, variables) should be imbued with the XRay + /// "never instrument" attribute. + /// WARNING: This is a deprecated field and will go away in the future. + std::vector XRayNeverInstrumentFiles; + + /// Paths to the XRay attribute list files, specifying which objects + /// (files, functions, variables) should be imbued with the appropriate XRay + /// attribute(s). + std::vector XRayAttrListFiles; + + clang::ObjCRuntime ObjCRuntime; + + CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified; + + std::string ObjCConstantStringClass; + + /// The name of the handler function to be called when -ftrapv is + /// specified. + /// + /// If none is specified, abort (GCC-compatible behaviour). + std::string OverflowHandler; + + /// The module currently being compiled as specified by -fmodule-name. + std::string ModuleName; + + /// The name of the current module, of which the main source file + /// is a part. If CompilingModule is set, we are compiling the interface + /// of this module, otherwise we are compiling an implementation file of + /// it. This starts as ModuleName in case -fmodule-name is provided and + /// changes during compilation to reflect the current module. + std::string CurrentModule; + + /// The names of any features to enable in module 'requires' decls + /// in addition to the hard-coded list in Module.cpp and the target features. + /// + /// This list is sorted. + std::vector ModuleFeatures; + /// Options for parsing comments. CommentOptions CommentOpts; -#define LANGOPT(Name, Bits, Default, Description) -#define TYPED_LANGOPT(Type, Name, Description) Type Name; -#include "clang/Basic/LangOptions.def" + /// A list of all -fno-builtin-* function names (e.g., memset). + std::vector NoBuiltinFuncs; + + /// Triples of the OpenMP targets that the host code codegen should + /// take into account in order to generate accurate offloading descriptors. + std::vector OMPTargetTriples; + + /// Name of the IR file that contains the result of the OpenMP target + /// host code generation. + std::string OMPHostIRFile; + + /// Indicates whether the front-end is explicitly told that the + /// input is a header file (i.e. -x c-header). + bool IsHeaderFile = false; /// SYCL integration header to be generated by the device compiler std::string SYCLIntHeader; diff --git a/clang/include/clang/Basic/TargetOptions.def b/clang/include/clang/Basic/TargetOptions.def deleted file mode 100644 index 33e746f012cea..0000000000000 --- a/clang/include/clang/Basic/TargetOptions.def +++ /dev/null @@ -1,88 +0,0 @@ -//===--- TargetOptions.def - Target option database -------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the target options. Users of this file must -// define the TYPED_TARGETOPT macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_TARGETOPT -#error Define the TYPED_TARGETOPT macro to handle target options -#endif - -TYPED_TARGETOPT(std::string, Triple, - "The name of the target triple to compile for.") - -TYPED_TARGETOPT( - std::string, HostTriple, - "When compiling for the device side, contains the triple used to " - "compile for the host.") - -TYPED_TARGETOPT(std::string, CPU, - "If given, the name of the target CPU to generate code for.") - -TYPED_TARGETOPT(std::string, TuneCPU, - "If given, the name of the target CPU to tune code for.") - -TYPED_TARGETOPT(std::string, FPMath, - "If given, the unit to use for floating point math.") - -TYPED_TARGETOPT(std::string, ABI, - "If given, the name of the target ABI to use.") - -TYPED_TARGETOPT(llvm::EABI, EABIVersion, "The EABI version to use.") - -TYPED_TARGETOPT(std::string, LinkerVersion, - "If given, the version string of the linker in use.") - -TYPED_TARGETOPT(std::vector, FeaturesAsWritten, - "The list of target specific features to enable or disable, as " - "written on the command line.") - -TYPED_TARGETOPT( - std::vector, Features, - "The list of target specific features to enable or disable -- this " - "should be a list of strings starting with by '+' or '-'.") - -TYPED_TARGETOPT(llvm::StringMap, FeatureMap, - "The map of which features have been enabled disabled based on " - "the command line.") - -TYPED_TARGETOPT(OpenCLOptions, SupportedOpenCLOptions, - "Supported OpenCL extensions and optional core features.") - -TYPED_TARGETOPT( - std::vector, OpenCLExtensionsAsWritten, - "The list of OpenCL extensions to enable or disable, as written on " - "the command line.") - -TYPED_TARGETOPT( - bool, ForceEnableInt128, - "If given, enables support for __int128_t and __uint128_t types.") - -TYPED_TARGETOPT( - bool, NVPTXUseShortPointers, - "If enabled, use 32-bit pointers for accessing const/local/shared " - "address space.") - -TYPED_TARGETOPT( - std::string, CodeModel, - "The code model to be used as specified by the user. Corresponds to " - "CodeModel::Model enum defined in include/llvm/Support/CodeGen.h, " - "plus \"default\" for the case when the user has not explicitly " - "specified a code model.") - -TYPED_TARGETOPT( - llvm::VersionTuple, SDKVersion, - "The version of the SDK which was used during the compilation. The option " - "is used for two different purposes. On Darwin the version is propagated " - "to LLVM where it's used to support SDK Version metadata (See D55673). " - "CUDA compilation uses it to control parts of CUDA compilation in clang " - "that depend on specific version of the CUDA SDK.") - -#undef TYPED_TARGETOPT diff --git a/clang/include/clang/Basic/TargetOptions.h b/clang/include/clang/Basic/TargetOptions.h index 1771c3bdbb611..d1cc024957dae 100644 --- a/clang/include/clang/Basic/TargetOptions.h +++ b/clang/include/clang/Basic/TargetOptions.h @@ -25,9 +25,69 @@ namespace clang { /// Options for controlling the target. class TargetOptions { public: -#define TYPED_TARGETOPT(Type, Name, Description) Type Name; -#include "clang/Basic/TargetOptions.def" - TargetOptions() : ForceEnableInt128(false), NVPTXUseShortPointers(false) {} + /// The name of the target triple to compile for. + std::string Triple; + + /// When compiling for the device side, contains the triple used to compile + /// for the host. + std::string HostTriple; + + /// If given, the name of the target CPU to generate code for. + std::string CPU; + + /// If given, the name of the target CPU to tune code for. + std::string TuneCPU; + + /// If given, the unit to use for floating point math. + std::string FPMath; + + /// If given, the name of the target ABI to use. + std::string ABI; + + /// The EABI version to use + llvm::EABI EABIVersion; + + /// If given, the version string of the linker in use. + std::string LinkerVersion; + + /// The list of target specific features to enable or disable, as written on the command line. + std::vector FeaturesAsWritten; + + /// The list of target specific features to enable or disable -- this should + /// be a list of strings starting with by '+' or '-'. + std::vector Features; + + /// The map of which features have been enabled disabled based on the command + /// line. + llvm::StringMap FeatureMap; + + /// Supported OpenCL extensions and optional core features. + OpenCLOptions SupportedOpenCLOptions; + + /// The list of OpenCL extensions to enable or disable, as written on + /// the command line. + std::vector OpenCLExtensionsAsWritten; + + /// If given, enables support for __int128_t and __uint128_t types. + bool ForceEnableInt128 = false; + + /// \brief If enabled, use 32-bit pointers for accessing const/local/shared + /// address space. + bool NVPTXUseShortPointers = false; + + // The code model to be used as specified by the user. Corresponds to + // CodeModel::Model enum defined in include/llvm/Support/CodeGen.h, plus + // "default" for the case when the user has not explicitly specified a + // code model. + std::string CodeModel; + + /// The version of the SDK which was used during the compilation. + /// The option is used for two different purposes: + /// * on darwin the version is propagated to LLVM where it's used + /// to support SDK Version metadata (See D55673). + /// * CUDA compilation uses it to control parts of CUDA compilation + /// in clang that depend on specific version of the CUDA SDK. + llvm::VersionTuple SDKVersion; }; } // end namespace clang diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 8634994bbfe68..39daf1cd3a8ec 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -830,6 +830,11 @@ PRAGMA_ANNOTATION(pragma_fp_contract) // handles them. PRAGMA_ANNOTATION(pragma_fenv_access) +// Annotation for #pragma STDC FENV_ROUND +// The lexer produces these so that they only take effect when the parser +// handles them. +PRAGMA_ANNOTATION(pragma_fenv_round) + // Annotation for #pragma float_control // The lexer produces these so that they only take effect when the parser // handles them. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index cebbb27609297..6021c063ed232 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1014,7 +1014,7 @@ defm cxx_static_destructors : OptOutFFlag<"c++-static-destructors", "", def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group, Flags<[CC1Option]>; -defm memprof : OptInFFlag<"memprof", "Enable", "Disable", " heap memory profiling">; +defm memory_profile : OptInFFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">; // Begin sanitizer flags. These should all be core options exposed in all driver // modes. @@ -2006,6 +2006,17 @@ def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group, def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group, HelpText<"Give inline C++ member functions hidden visibility by default">, Flags<[CC1Option]>; +def fvisibility_inlines_hidden_static_local_var : + Flag<["-"], "fvisibility-inlines-hidden-static-local-var">, Group, + HelpText<"When -fvisibility-inlines-hidden is enabled, static variables in " + "inline C++ member functions will also be given hidden visibility " + "by default">, + Flags<[CC1Option]>; +def fno_visibility_inlines_hidden_static_local_var : + Flag<["-"], "fno-visibility-inlines-hidden-static-local-var">, Group, + HelpText<"Disables -fvisibility-inlines-hidden-static-local-var " + "(this is the default on non-darwin targets)">, + Flags<[CC1Option]>; def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group, HelpText<"Give global types 'default' visibility and global functions and " "variables 'hidden' visibility by default">; @@ -2812,7 +2823,7 @@ def no_pie : Flag<["-"], "no-pie">, Alias; def noprebind : Flag<["-"], "noprebind">; def noprofilelib : Flag<["-"], "noprofilelib">; def noseglinkedit : Flag<["-"], "noseglinkedit">; -def nostartfiles : Flag<["-"], "nostartfiles">; +def nostartfiles : Flag<["-"], "nostartfiles">, Group; def nostdinc : Flag<["-"], "nostdinc">, Flags<[CoreOption]>; def nostdlibinc : Flag<["-"], "nostdlibinc">; def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>, @@ -2915,7 +2926,7 @@ def segs__read__ : Joined<["-"], "segs_read_">; def shared_libgcc : Flag<["-"], "shared-libgcc">; def shared : Flag<["-", "--"], "shared">, Group; def single__module : Flag<["-"], "single_module">; -def specs_EQ : Joined<["-", "--"], "specs=">; +def specs_EQ : Joined<["-", "--"], "specs=">, Group; def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>; def static_libgcc : Flag<["-"], "static-libgcc">; def static_libstdcxx : Flag<["-"], "static-libstdc++">; @@ -3561,6 +3572,15 @@ def fsycl_dead_args_optimization : Flag<["-"], "fsycl-dead-args-optimization">, def fno_sycl_dead_args_optimization : Flag<["-"], "fno-sycl-dead-args-optimization">, Group, Flags<[NoArgumentUnused, CoreOption]>, HelpText<"Disables " "elimination of DPC++ dead kernel arguments">; +def fsycl_device_lib_EQ : CommaJoined<["-"], "fsycl-device-lib=">, Group, Flags<[DriverOption, CoreOption]>, + Values<"libc, libm-fp32, libm-fp64, all">, HelpText<"Control inclusion of " + "device libraries into device binary linkage. Valid arguments " + "are libc, libm-fp32, libm-fp64, all">; +def fno_sycl_device_lib_EQ : CommaJoined<["-"], "fno-sycl-device-lib=">, Group, Flags<[DriverOption, CoreOption]>, + Values<"libc, libm-fp32, libm-fp64, all">, HelpText<"Control exclusion of " + "device libraries from device binary linkage. Valid arguments " + "are libc, libm-fp32, libm-fp64, all">; + //===----------------------------------------------------------------------===// // CC1 Options //===----------------------------------------------------------------------===// @@ -4782,6 +4802,9 @@ def _SLASH_openmp : CLFlag<"openmp">, HelpText<"Enable OpenMP support">, def _SLASH_openmp_experimental : CLFlag<"openmp:experimental">, HelpText<"Enable OpenMP support with experimental SIMD support">, Alias; +def _SLASH_tune : CLCompileJoined<"tune:">, + HelpText<"Set CPU for optimization without affecting instruction set">, + Alias; // Non-aliases: diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 7b003aab3eb33..8e5b2afdcb976 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -111,4 +111,5 @@ TYPE("fpga_aocx", FPGA_AOCX, INVALID, "aocx", phases TYPE("fpga_aocr", FPGA_AOCR, INVALID, "aocr", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("fpga_aoco", FPGA_AOCO, INVALID, "aoco", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("fpga_dependencies", FPGA_Dependencies, INVALID, "d", phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("fpga_dependencies_list", FPGA_Dependencies_List, INVALID, "txt", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("none", Nothing, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 269eab971a2cb..6bb828d60071f 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -583,6 +583,24 @@ struct FormatStyle { /// The template declaration breaking style to use. BreakTemplateDeclarationsStyle AlwaysBreakTemplateDeclarations; + /// A vector of strings that should be interpreted as attributes/qualifiers + /// instead of identifiers. This can be useful for language extensions or + /// static analyzer annotations. + /// + /// For example: + /// \code + /// x = (char *__capability)&y; + /// int function(void) __ununsed; + /// void only_writes_to_buffer(char *__output buffer); + /// \endcode + /// + /// In the .clang-format configuration file, this can be configured like: + /// \code{.yaml} + /// AttributeMacros: ['__capability', '__output', '__ununsed'] + /// \endcode + /// + std::vector AttributeMacros; + /// If ``false``, a function call's arguments will either be all on the /// same line or will have one line each. /// \code @@ -2351,6 +2369,7 @@ struct FormatStyle { R.AlwaysBreakBeforeMultilineStrings && AlwaysBreakTemplateDeclarations == R.AlwaysBreakTemplateDeclarations && + AttributeMacros == R.AttributeMacros && BinPackArguments == R.BinPackArguments && BinPackParameters == R.BinPackParameters && BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index c8a95ae69d72b..c723fc084c854 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -19,10 +19,9 @@ #include "clang/Frontend/FrontendOptions.h" #include "clang/Frontend/MigratorOptions.h" #include "clang/Frontend/PreprocessorOutputOptions.h" -#include "clang/Sema/CodeCompleteOptions.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/ArrayRef.h" #include #include @@ -87,9 +86,6 @@ class CompilerInvocationBase { LangOptions *getLangOpts() { return LangOpts.get(); } const LangOptions *getLangOpts() const { return LangOpts.get(); } - CommentOptions &getCommentOpts() { return LangOpts->CommentOpts; } - const CommentOptions &getCommentOpts() const { return LangOpts->CommentOpts; } - TargetOptions &getTargetOpts() { return *TargetOpts.get(); } const TargetOptions &getTargetOpts() const { return *TargetOpts.get(); } @@ -231,14 +227,6 @@ class CompilerInvocation : public CompilerInvocationBase { FrontendOptions &getFrontendOpts() { return FrontendOpts; } const FrontendOptions &getFrontendOpts() const { return FrontendOpts; } - CodeCompleteOptions &getCodeCompleteOpts() { - return FrontendOpts.CodeCompleteOpts; - } - - const CodeCompleteOptions &getCodeCompleteOpts() const { - return FrontendOpts.CodeCompleteOpts; - } - PreprocessorOutputOptions &getPreprocessorOutputOpts() { return PreprocessorOutputOpts; } diff --git a/clang/include/clang/Frontend/DependencyOutputOptions.def b/clang/include/clang/Frontend/DependencyOutputOptions.def deleted file mode 100644 index c018e900fc106..0000000000000 --- a/clang/include/clang/Frontend/DependencyOutputOptions.def +++ /dev/null @@ -1,52 +0,0 @@ -//===--- DependencyOutputOptions.def -------------------------------C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file contains the DependencyOutput options, to use this file one needs -// to define the TYPED_DEPENDENCY_OUTPUTOPT and/or the DEPENDECY_OUTPUTOPT macro -// to get more information about bitfields. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_DEPENDENCY_OUTPUTOPT -#define TYPED_DEPENDENCY_OUTPUTOPT(Type, Name, Description) -#endif - -#ifndef DEPENDENCY_OUTPUTOPT -#define DEPENDENCY_OUTPUTOPT(Name, Bits, Description) \ - TYPED_DEPENDENCY_OUTPUTOPT(unsigned, Name, Description) -#endif - -DEPENDENCY_OUTPUTOPT(IncludeSystemHeaders, 1, "Include system header dependencies.") -DEPENDENCY_OUTPUTOPT(ShowHeaderIncludes, 1, "Show header inclusions (-H).") -DEPENDENCY_OUTPUTOPT(UsePhonyTargets, 1, "Include phony targets for each dependency, which can " - "avoid some 'make' problems.") -DEPENDENCY_OUTPUTOPT(AddMissingHeaderDeps, 1, "Add missing headers to dependency list.") -DEPENDENCY_OUTPUTOPT(IncludeModuleFiles, 1, "Include module file dependencies.") - -TYPED_DEPENDENCY_OUTPUTOPT(ShowIncludesDestination, ShowIncludesDest, "Destination of cl.exe style /showIncludes info.") - -TYPED_DEPENDENCY_OUTPUTOPT(DependencyOutputFormat, OutputFormat, "The format for the dependency file") - -TYPED_DEPENDENCY_OUTPUTOPT(std::string, OutputFile, "The file to write dependency output to.") - -TYPED_DEPENDENCY_OUTPUTOPT(std::string, DependencyFilter, "Dependency output which is prefixed with this string is filtered from the dependency output.") - -TYPED_DEPENDENCY_OUTPUTOPT(std::string, HeaderIncludeOutputFile, "The file to write header include output to. This is orthogonal to ShowHeaderIncludes (-H) and will include headers mentioned in the predefines buffer. If the output file is \"-\", output will be sent to stderr.") - -TYPED_DEPENDENCY_OUTPUTOPT(std::vector, Targets, "A list of names to use as the targets in the dependency file; this list must contain at least one entry.") - -TYPED_DEPENDENCY_OUTPUTOPT(std::vector, ExtraDeps, "A list of filenames to be used as extra dependencies for every target.") - -TYPED_DEPENDENCY_OUTPUTOPT(std::string, ShowIncludesPretendHeader, "In /showIncludes mode, pretend the main TU is a header with this name.") - -TYPED_DEPENDENCY_OUTPUTOPT(std::string, DOTOutputFile, "The file to write GraphViz-formatted header dependencies to.") - -TYPED_DEPENDENCY_OUTPUTOPT(std::string, ModuleDependencyOutputDir, "The directory to copy module dependencies to when collecting them.") - -#undef TYPED_DEPENDENCY_OUTPUTOPT -#undef DEPENDENCY_OUTPUTOPT \ No newline at end of file diff --git a/clang/include/clang/Frontend/DependencyOutputOptions.h b/clang/include/clang/Frontend/DependencyOutputOptions.h index 581e9b5a544b8..4480171ce212c 100644 --- a/clang/include/clang/Frontend/DependencyOutputOptions.h +++ b/clang/include/clang/Frontend/DependencyOutputOptions.h @@ -24,15 +24,53 @@ enum class DependencyOutputFormat { Make, NMake }; /// file generation. class DependencyOutputOptions { public: -#define TYPED_DEPENDENCY_OUTPUTOPT(Type, Name, Description) Type Name; -#define DEPENDENCY_OUTPUTOPT(Name, Bits, Description) unsigned Name : Bits; -#include "clang/Frontend/DependencyOutputOptions.def" + unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies. + unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H). + unsigned UsePhonyTargets : 1; ///< Include phony targets for each + /// dependency, which can avoid some 'make' + /// problems. + unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list + unsigned IncludeModuleFiles : 1; ///< Include module file dependencies. + + /// Destination of cl.exe style /showIncludes info. + ShowIncludesDestination ShowIncludesDest = ShowIncludesDestination::None; + + /// The format for the dependency file. + DependencyOutputFormat OutputFormat = DependencyOutputFormat::Make; + + /// The file to write dependency output to. + std::string OutputFile; + + /// The file to write header include output to. This is orthogonal to + /// ShowHeaderIncludes (-H) and will include headers mentioned in the + /// predefines buffer. If the output file is "-", output will be sent to + /// stderr. + std::string HeaderIncludeOutputFile; + + /// A list of names to use as the targets in the dependency file; this list + /// must contain at least one entry. + std::vector Targets; + + /// A list of filenames to be used as extra dependencies for every target. + std::vector ExtraDeps; + + /// In /showIncludes mode, pretend the main TU is a header with this name. + std::string ShowIncludesPretendHeader; + + /// The file to write GraphViz-formatted header dependencies to. + std::string DOTOutputFile; + + /// The directory to copy module dependencies to when collecting them. + std::string ModuleDependencyOutputDir; + + /// Dependency output which is prefixed with this string is filtered from + /// the dependency output. + std::string DependencyFilter; + public: DependencyOutputOptions() : IncludeSystemHeaders(0), ShowHeaderIncludes(0), UsePhonyTargets(0), - AddMissingHeaderDeps(0), IncludeModuleFiles(0), - ShowIncludesDest(ShowIncludesDestination::None), - OutputFormat(DependencyOutputFormat::Make) {} + AddMissingHeaderDeps(0), IncludeModuleFiles(0) {} }; } // end namespace clang diff --git a/clang/include/clang/Frontend/FrontendOptions.def b/clang/include/clang/Frontend/FrontendOptions.def deleted file mode 100644 index c6188d9cf0255..0000000000000 --- a/clang/include/clang/Frontend/FrontendOptions.def +++ /dev/null @@ -1,179 +0,0 @@ -//===--- FrontendOptions.def - FileSystem option database -----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the Frontend options. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_FRONTENDOPT -#define TYPED_FRONTENDOPT(Type, Name, Description) -#endif - -#ifndef FRONTENDOPT -#define FRONTENDOPT(Name, Bits, Description) \ - TYPED_FRONTENDOPT(unsigned, Name, Description) -#endif - -FRONTENDOPT(DisableFree, 1, "Disable memory freeing on exit.") - -FRONTENDOPT(RelocatablePCH, 1, - "When generating PCH files, instruct the AST writer to create " - "relocatable PCH files.") - -FRONTENDOPT(ShowHelp, 1, "Show the -help text.") - -FRONTENDOPT(ShowStats, 1, "Show frontend performance metrics and statistics.") - -FRONTENDOPT(ShowTimers, 1, "Show timers for individual actions.") - -FRONTENDOPT(PrintSupportedCPUs, 1, - "print the supported cpus for the current target") - -FRONTENDOPT(TimeTrace, 1, "Output time trace profile.") - -FRONTENDOPT(ShowVersion, 1, "Show the -version text.") - -FRONTENDOPT(FixWhatYouCan, 1, "Apply fixes even if there are unfixable errors.") - -FRONTENDOPT(FixOnlyWarnings, 1, "Apply fixes only for warnings.") - -FRONTENDOPT(FixAndRecompile, 1, "Apply fixes and recompile.") - -FRONTENDOPT(FixToTemporaries, 1, "Apply fixes to temporary files.") - -FRONTENDOPT(ARCMTAction, 3, "") - -FRONTENDOPT(ARCMTMigrateEmitARCErrors, 1, - "Emit ARC errors even if the migrator can fix them.") - -FRONTENDOPT(SkipFunctionBodies, 1, - "Skip over function bodies to speed up parsing in cases you do not " - "need them (e.g. with code completion).") - -FRONTENDOPT(UseGlobalModuleIndex, 1, - "Whether we can use the global module index if available.") - -FRONTENDOPT(GenerateGlobalModuleIndex, 1, - "Whether we can generate the global module index if needed.") - -FRONTENDOPT(ASTDumpDecls, 1, - "Whether we include declaration dumps in AST dumps.") - -FRONTENDOPT(ASTDumpAll, 1, - "Whether we deserialize all decls when forming AST dumps.") - -FRONTENDOPT(ASTDumpLookups, 1, - "Whether we include lookup table dumps in AST dumps.") - -FRONTENDOPT(ASTDumpDeclTypes, 1, - "Whether we include declaration type dumps in AST dumps.") - -FRONTENDOPT(BuildingImplicitModule, 1, - "Whether we are performing an implicit module build.") - -FRONTENDOPT(ModulesEmbedAllFiles, 1, - "Whether we should embed all used files into the PCM file.") - -FRONTENDOPT(IncludeTimestamps, 1, - "Whether timestamps should be written to the produced PCH file.") - -FRONTENDOPT(UseTemporary, 1, - "Should a temporary file be used during compilation.") - -FRONTENDOPT(IsSystemModule, 1, - "When using -emit-module, treat the modulemap as a system module.") - -TYPED_FRONTENDOPT(ASTDumpOutputFormat, ASTDumpFormat, - "Specifies the output format of the AST.") - -TYPED_FRONTENDOPT(unsigned, ObjCMTAction, "") - -TYPED_FRONTENDOPT(std::string, ObjCMTWhiteListPath, "") - -TYPED_FRONTENDOPT(std::string, MTMigrateDir, "") - -TYPED_FRONTENDOPT(std::string, ARCMTMigrateReportOut, "") - -TYPED_FRONTENDOPT(InputsTy, Inputs, "The input files and their types.") - -TYPED_FRONTENDOPT( - std::string, OriginalModuleMap, - "When the input is a module map, the original module map file from which " - "that map was inferred, if any (for umbrella modules).") - -TYPED_FRONTENDOPT(std::string, OutputFile, "The output file, if any.") - -TYPED_FRONTENDOPT(std::string, FixItSuffix, - "If given, the new suffix for fix-it rewritten files.") - -TYPED_FRONTENDOPT(std::string, ASTDumpFilter, - "If given, filter dumped AST Decl nodes by this substring.") - -TYPED_FRONTENDOPT(ParsedSourceLocation, CodeCompletionAt, - "If given, enable code completion at the provided location.") - -TYPED_FRONTENDOPT(frontend::ActionKind, ProgramAction, - "The frontend action to perform.") - -TYPED_FRONTENDOPT(std::string, ActionName, - "The name of the action to run when using a plugin action.") - -TYPED_FRONTENDOPT(PluginArgsTy, PluginArgs, "Args to pass to the plugins") - -TYPED_FRONTENDOPT( - std::vector, AddPluginActions, - "The list of plugin actions to run in addition to the normal action.") - -TYPED_FRONTENDOPT(std::vector, Plugins, - "The list of plugins to load.") - -TYPED_FRONTENDOPT(std::vector>, - ModuleFileExtensions, "The list of module file extensions.") - -TYPED_FRONTENDOPT( - std::vector, ModuleMapFiles, - "The list of module map files to load before processing the input.") - -TYPED_FRONTENDOPT(std::vector, ModuleFiles, - "The list of additional prebuilt module files to load before " - "processing the input.") - -TYPED_FRONTENDOPT(std::vector, ModulesEmbedFiles, - "The list of files to embed into the compiled module file.") - -TYPED_FRONTENDOPT(std::vector, ASTMergeFiles, - "The list of AST files to merge.") - -TYPED_FRONTENDOPT( - std::vector, LLVMArgs, - "A list of arguments to forward to LLVM's option processing; this should " - "only be used for debugging and experimental features.") - -TYPED_FRONTENDOPT(std::string, OverrideRecordLayoutsFile, - "File name of the file that will provide record layouts (in " - "the format produced by -fdump-record-layouts).") - -TYPED_FRONTENDOPT(std::string, AuxTriple, - "Auxiliary triple for CUDA/HIP compilation.") - -TYPED_FRONTENDOPT(Optional, AuxTargetCPU, - "Auxiliary target CPU for CUDA/HIP compilation.") - -TYPED_FRONTENDOPT(Optional>, AuxTargetFeatures, - "Auxiliary target features for CUDA/HIP compilation.") - -TYPED_FRONTENDOPT(std::string, StatsFile, "Filename to write statistics to.") - -TYPED_FRONTENDOPT( - unsigned, TimeTraceGranularity, - "Minimum time granularity (in microseconds) traced by time profiler.") - -TYPED_FRONTENDOPT(InputKind, DashX, "Input Kind") - -#undef TYPED_FRONTENDOPT -#undef FRONTENDOPT \ No newline at end of file diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 5dccdf50ca462..b2be33032c08d 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -226,14 +226,94 @@ class FrontendInputFile { /// FrontendOptions - Options for controlling the behavior of the frontend. class FrontendOptions { public: - using PluginArgsTy = - std::unordered_map>; + /// Disable memory freeing on exit. + unsigned DisableFree : 1; - using InputsTy = llvm::SmallVector; + /// When generating PCH files, instruct the AST writer to create relocatable + /// PCH files. + unsigned RelocatablePCH : 1; + + /// Show the -help text. + unsigned ShowHelp : 1; + + /// Show frontend performance metrics and statistics. + unsigned ShowStats : 1; + + /// Show timers for individual actions. + unsigned ShowTimers : 1; + + /// print the supported cpus for the current target + unsigned PrintSupportedCPUs : 1; + + /// Output time trace profile. + unsigned TimeTrace : 1; + + /// Show the -version text. + unsigned ShowVersion : 1; + + /// Apply fixes even if there are unfixable errors. + unsigned FixWhatYouCan : 1; + + /// Apply fixes only for warnings. + unsigned FixOnlyWarnings : 1; + + /// Apply fixes and recompile. + unsigned FixAndRecompile : 1; + + /// Apply fixes to temporary files. + unsigned FixToTemporaries : 1; + + /// Emit ARC errors even if the migrator can fix them. + unsigned ARCMTMigrateEmitARCErrors : 1; + + /// Skip over function bodies to speed up parsing in cases you do not need + /// them (e.g. with code completion). + unsigned SkipFunctionBodies : 1; + + /// Whether we can use the global module index if available. + unsigned UseGlobalModuleIndex : 1; + + /// Whether we can generate the global module index if needed. + unsigned GenerateGlobalModuleIndex : 1; + + /// Whether we include declaration dumps in AST dumps. + unsigned ASTDumpDecls : 1; + + /// Whether we deserialize all decls when forming AST dumps. + unsigned ASTDumpAll : 1; + + /// Whether we include lookup table dumps in AST dumps. + unsigned ASTDumpLookups : 1; + + /// Whether we include declaration type dumps in AST dumps. + unsigned ASTDumpDeclTypes : 1; + + /// Whether we are performing an implicit module build. + unsigned BuildingImplicitModule : 1; + + /// Whether we should embed all used files into the PCM file. + unsigned ModulesEmbedAllFiles : 1; + + /// Whether timestamps should be written to the produced PCH file. + unsigned IncludeTimestamps : 1; + + /// Should a temporary file be used during compilation. + unsigned UseTemporary : 1; + + /// When using -emit-module, treat the modulemap as a system module. + unsigned IsSystemModule : 1; CodeCompleteOptions CodeCompleteOpts; - enum { ARCMT_None, ARCMT_Check, ARCMT_Modify, ARCMT_Migrate }; + /// Specifies the output format of the AST. + ASTDumpOutputFormat ASTDumpFormat = ADOF_Default; + + enum { + ARCMT_None, + ARCMT_Check, + ARCMT_Modify, + ARCMT_Migrate + } ARCMTAction = ARCMT_None; enum { ObjCMT_None = 0, @@ -280,18 +360,92 @@ class FrontendOptions { /// Enable converting setter/getter expressions to property-dot syntx. ObjCMT_PropertyDotSyntax = 0x1000, - ObjCMT_MigrateDecls = - (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty | - ObjCMT_Annotation | ObjCMT_Instancetype | ObjCMT_NsMacros | - ObjCMT_ProtocolConformance | ObjCMT_NsAtomicIOSOnlyProperty | - ObjCMT_DesignatedInitializer), + ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty | + ObjCMT_Annotation | ObjCMT_Instancetype | + ObjCMT_NsMacros | ObjCMT_ProtocolConformance | + ObjCMT_NsAtomicIOSOnlyProperty | + ObjCMT_DesignatedInitializer), ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax) }; + unsigned ObjCMTAction = ObjCMT_None; + std::string ObjCMTWhiteListPath; + + std::string MTMigrateDir; + std::string ARCMTMigrateReportOut; + + /// The input files and their types. + SmallVector Inputs; + + /// When the input is a module map, the original module map file from which + /// that map was inferred, if any (for umbrella modules). + std::string OriginalModuleMap; + + /// The output file, if any. + std::string OutputFile; + + /// If given, the new suffix for fix-it rewritten files. + std::string FixItSuffix; + + /// If given, filter dumped AST Decl nodes by this substring. + std::string ASTDumpFilter; + + /// If given, enable code completion at the provided location. + ParsedSourceLocation CodeCompletionAt; + + /// The frontend action to perform. + frontend::ActionKind ProgramAction = frontend::ParseSyntaxOnly; + + /// The name of the action to run when using a plugin action. + std::string ActionName; + + /// Args to pass to the plugins + std::unordered_map> PluginArgs; + + /// The list of plugin actions to run in addition to the normal action. + std::vector AddPluginActions; + + /// The list of plugins to load. + std::vector Plugins; + + /// The list of module file extensions. + std::vector> ModuleFileExtensions; + + /// The list of module map files to load before processing the input. + std::vector ModuleMapFiles; + + /// The list of additional prebuilt module files to load before + /// processing the input. + std::vector ModuleFiles; + + /// The list of files to embed into the compiled module file. + std::vector ModulesEmbedFiles; + + /// The list of AST files to merge. + std::vector ASTMergeFiles; + + /// A list of arguments to forward to LLVM's option processing; this + /// should only be used for debugging and experimental features. + std::vector LLVMArgs; + + /// File name of the file that will provide record layouts + /// (in the format produced by -fdump-record-layouts). + std::string OverrideRecordLayoutsFile; + + /// Auxiliary triple for CUDA/HIP compilation. + std::string AuxTriple; + + /// Auxiliary target CPU for CUDA/HIP compilation. + Optional AuxTargetCPU; + + /// Auxiliary target features for CUDA/HIP compilation. + Optional> AuxTargetFeatures; + + /// Filename to write statistics to. + std::string StatsFile; -#define FRONTENDOPT(Name, Bits, Description) unsigned Name : Bits; -#define TYPED_FRONTENDOPT(Type, Name, Description) Type Name; -#include "clang/Frontend/FrontendOptions.def" + /// Minimum time granularity (in microseconds) traced by time profiler. + unsigned TimeTraceGranularity; public: FrontendOptions() @@ -299,14 +453,11 @@ class FrontendOptions { ShowStats(false), ShowTimers(false), TimeTrace(false), ShowVersion(false), FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false), FixToTemporaries(false), - ARCMTAction(ARCMT_None), ARCMTMigrateEmitARCErrors(false), - SkipFunctionBodies(false), UseGlobalModuleIndex(true), - GenerateGlobalModuleIndex(true), ASTDumpDecls(false), - ASTDumpLookups(false), BuildingImplicitModule(false), - ModulesEmbedAllFiles(false), IncludeTimestamps(true), - UseTemporary(true), ASTDumpFormat(ADOF_Default), - ObjCMTAction(ObjCMT_None), ProgramAction(frontend::ParseSyntaxOnly), - TimeTraceGranularity(500), DashX() {} + ARCMTMigrateEmitARCErrors(false), SkipFunctionBodies(false), + UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), + ASTDumpDecls(false), ASTDumpLookups(false), + BuildingImplicitModule(false), ModulesEmbedAllFiles(false), + IncludeTimestamps(true), UseTemporary(true), TimeTraceGranularity(500) {} /// getInputKindForExtension - Return the appropriate input kind for a file /// extension. For example, "c" would return Language::C. diff --git a/clang/include/clang/Frontend/MigratorOptions.def b/clang/include/clang/Frontend/MigratorOptions.def deleted file mode 100644 index fbbcc6b686fdf..0000000000000 --- a/clang/include/clang/Frontend/MigratorOptions.def +++ /dev/null @@ -1,27 +0,0 @@ -//===--- MigratorOptions.def - Migrator option database ---------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the migrator options. Users of this file must -// define the TYPED_MIGRATOROPT macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_MIGRATOROPT -#define TYPED_MIGRATOROPT(Type, Name, Description) -#endif - -#ifndef MIGRATOROPT -#define MIGRATOROPT(Name, Bits, Description) \ - TYPED_MIGRATOROPT(unsigned, Name, Description) -#endif - -MIGRATOROPT(NoNSAllocReallocError, 1, "") -MIGRATOROPT(NoFinalizeRemoval, 1, "") - -#undef TYPED_MIGRATOROPT -#undef MIGRATOROPT diff --git a/clang/include/clang/Frontend/MigratorOptions.h b/clang/include/clang/Frontend/MigratorOptions.h index f5ee9bba9dec0..cf50ffcf0c4f5 100644 --- a/clang/include/clang/Frontend/MigratorOptions.h +++ b/clang/include/clang/Frontend/MigratorOptions.h @@ -18,10 +18,13 @@ namespace clang { class MigratorOptions { public: -#define MIGRATOROPT(Name, Bits, Description) unsigned Name : Bits; -#include "clang/Frontend/MigratorOptions.def" - - MigratorOptions() : NoNSAllocReallocError(0), NoFinalizeRemoval(0) {} + unsigned NoNSAllocReallocError : 1; + unsigned NoFinalizeRemoval : 1; + MigratorOptions() { + NoNSAllocReallocError = 0; + NoFinalizeRemoval = 0; + } }; + } #endif diff --git a/clang/include/clang/Frontend/PreprocessorOutputOptions.def b/clang/include/clang/Frontend/PreprocessorOutputOptions.def deleted file mode 100644 index aad2f5eb7294b..0000000000000 --- a/clang/include/clang/Frontend/PreprocessorOutputOptions.def +++ /dev/null @@ -1,46 +0,0 @@ -//=== PreprocessorOutputOptions.def - FileSystem option database -*- C++-*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the PreprocessorOutput options. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_PREPROCESSOR_OUTPUTOPT -#define TYPED_PREPROCESSOR_OUTPUTOPT(Type, Name, Description) -#endif - -#ifndef PREPROCESSOR_OUTPUTOPT -#define PREPROCESSOR_OUTPUTOPT(Name, Bits, Description) \ - TYPED_PREPROCESSOR_OUTPUTOPT(unsigned, Name, Description) -#endif - -PREPROCESSOR_OUTPUTOPT(ShowCPP, 1, "Print normal preprocessed output.") - -PREPROCESSOR_OUTPUTOPT(ShowComments, 1, "Show comments.") - -PREPROCESSOR_OUTPUTOPT(ShowLineMarkers, 1, "Show \#line markers.") - -PREPROCESSOR_OUTPUTOPT(UseLineDirectives, 1, - "Use \#line instead of GCC-style \# N.") - -PREPROCESSOR_OUTPUTOPT(ShowMacroComments, 1, "Show comments, even in macros.") - -PREPROCESSOR_OUTPUTOPT(ShowMacros, 1, "Print macro definitions.") - -PREPROCESSOR_OUTPUTOPT( - ShowIncludeDirectives, 1, - "Print includes, imports etc. within preprocessed output.") - -PREPROCESSOR_OUTPUTOPT(RewriteIncludes, 1, - "Preprocess include directives only.") - -PREPROCESSOR_OUTPUTOPT(RewriteImports, 1, - "Include contents of transitively-imported modules.") - -#undef TYPED_PREPROCESSOR_OUTPUTOPT -#undef PREPROCESSOR_OUTPUTOPT \ No newline at end of file diff --git a/clang/include/clang/Frontend/PreprocessorOutputOptions.h b/clang/include/clang/Frontend/PreprocessorOutputOptions.h index ab4f25e394a27..72e5ad1137fb7 100644 --- a/clang/include/clang/Frontend/PreprocessorOutputOptions.h +++ b/clang/include/clang/Frontend/PreprocessorOutputOptions.h @@ -15,9 +15,15 @@ namespace clang { /// output (e.g., -E). class PreprocessorOutputOptions { public: -#define PREPROCESSOR_OUTPUTOPT(Name, Bits, Description) unsigned Name : Bits; -#define TYPED_PREPROCESSOR_OUTPUTOPT(Type, Name, Description) Type Name; -#include "clang/Frontend/PreprocessorOutputOptions.def" + unsigned ShowCPP : 1; ///< Print normal preprocessed output. + unsigned ShowComments : 1; ///< Show comments. + unsigned ShowLineMarkers : 1; ///< Show \#line markers. + unsigned UseLineDirectives : 1; ///< Use \#line instead of GCC-style \# N. + unsigned ShowMacroComments : 1; ///< Show comments, even in macros. + unsigned ShowMacros : 1; ///< Print macro definitions. + unsigned ShowIncludeDirectives : 1; ///< Print includes, imports etc. within preprocessed output. + unsigned RewriteIncludes : 1; ///< Preprocess include directives only. + unsigned RewriteImports : 1; ///< Include contents of transitively-imported modules. public: PreprocessorOutputOptions() { diff --git a/clang/include/clang/Lex/HeaderSearchOptions.def b/clang/include/clang/Lex/HeaderSearchOptions.def deleted file mode 100644 index 79fd196c8f905..0000000000000 --- a/clang/include/clang/Lex/HeaderSearchOptions.def +++ /dev/null @@ -1,136 +0,0 @@ -//===--- HeaderSearchOptions.def - HeaderSearch option database -*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the header search options. Users of this file must -// define the HEADERSEARCHOPT macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#ifndef HEADERSEARCHOPT -#define HEADERSEARCHOPT(Name, Bits, Description) \ - TYPED_HEADERSEARCHOPT(unsigned, Name, Description) -#endif - -#ifndef TYPED_HEADERSEARCHOPT -#define TYPED_HEADERSEARCHOPT(Type, Name, Description) -#endif - -TYPED_HEADERSEARCHOPT(std::string, Sysroot, - "If non-empty, the directory to use as a \"virtual " - "system root\" for include paths.") - -TYPED_HEADERSEARCHOPT(std::string, ModuleFormat, - "The module/pch container format.") - -HEADERSEARCHOPT(DisableModuleHash, 1, - "Whether we should disable the use of the hash string within " - "the module cache. Note: Only used for testing!") - -HEADERSEARCHOPT(ImplicitModuleMaps, 1, - "Implicit module maps. This option is enabld by default when " - "modules is enabled.") - -HEADERSEARCHOPT( - ModuleMapFileHomeIsCwd, 1, - "Set the 'home directory' of a module map file to the current working " - "directory (or the home directory of the module map file that contained " - "the 'extern module' directive importing this module map file if any) " - "rather than the directory containing the module map file. The home " - "directory is where we look for files named in the module map file.") - -HEADERSEARCHOPT(UseBuiltinIncludes, 1, "Include the compiler builtin includes.") - -HEADERSEARCHOPT(UseStandardSystemIncludes, 1, - "Include the system standard include search directories.") - -HEADERSEARCHOPT( - UseStandardCXXIncludes, 1, - "Include the system standard C++ library include search directories.") - -HEADERSEARCHOPT(UseLibcxx, 1, "Use libc++ instead of the default libstdc++.") - -HEADERSEARCHOPT(Verbose, 1, - "Whether header search information should be output as for -v.") - -HEADERSEARCHOPT( - ModulesValidateOncePerBuildSession, 1, - "If true, skip verifying input files used by modules if the module was " - "already verified during this build session (see BuildSessionTimestamp).") - -HEADERSEARCHOPT( - ModulesValidateSystemHeaders, 1, - "Whether to validate system input files when a module is loaded.") - -HEADERSEARCHOPT(ValidateASTInputFilesContent, 1, - "Whether the content of input files should be hashed and used " - "to validate consistency.") - -HEADERSEARCHOPT(UseDebugInfo, 1, - "Whether the module includes debug information (-gmodules).") - -HEADERSEARCHOPT(ModulesValidateDiagnosticOptions, 1, "") - -HEADERSEARCHOPT(ModulesHashContent, 1, "") - -HEADERSEARCHOPT(ModulesStrictContextHash, 1, - "Whether we should include all things that could impact the " - "module in the hash. This includes things like the full header " - "search path, and enabled diagnostics.") - -TYPED_HEADERSEARCHOPT(std::vector, UserEntries, - "User specified include entries.") - -TYPED_HEADERSEARCHOPT(std::vector, SystemHeaderPrefixes, - "User-specified system header prefixes.") - -TYPED_HEADERSEARCHOPT(std::string, ResourceDir, - "The directory which holds the compiler resource files " - "(builtin includes, etc.).") - -TYPED_HEADERSEARCHOPT(std::string, ModuleCachePath, - "The directory used for the module cache.") - -TYPED_HEADERSEARCHOPT(std::string, ModuleUserBuildPath, - "The directory used for a user build.") - -TYPED_HEADERSEARCHOPT(PrebuiltModuleFilesTy, PrebuiltModuleFiles, - "The mapping of module names to prebuilt module files.") - -TYPED_HEADERSEARCHOPT(std::vector, PrebuiltModulePaths, - "The directories used to load prebuilt module files.") - -TYPED_HEADERSEARCHOPT( - unsigned, ModuleCachePruneInterval, - "The interval (in seconds) between pruning operations. This operation is " - "expensive, because it requires Clang to walk through the directory " - "structure of the module cache, stat()'ing and removing files. The " - "default value is large, e.g., the operation runs once a week.") - -TYPED_HEADERSEARCHOPT( - unsigned, ModuleCachePruneAfter, - "The time (in seconds) after which an unused module file will be " - "considered unused and will, therefore, be pruned. When the module cache " - "is pruned, any module file that has not been accessed in this many " - "seconds will be removed. The default value is large, e.g., a month, to " - "avoid forcing infrequently-used modules to be regenerated often.") - -TYPED_HEADERSEARCHOPT( - uint64_t, BuildSessionTimestamp, - "The time in seconds when the build session started. This time is used " - "by other optimizations in header search and module loading.") - -TYPED_HEADERSEARCHOPT(ModulesIgnoreMacrosTy, ModulesIgnoreMacros, - "The set of macro names that should be ignored for the " - "purposes of computing the module hash.") - -TYPED_HEADERSEARCHOPT( - std::vector, VFSOverlayFiles, - "The set of user-provided virtual filesystem overlay files.") - -#undef HEADERSEARCHOPT -#undef TYPED_HEADERSEARCHOPT diff --git a/clang/include/clang/Lex/HeaderSearchOptions.h b/clang/include/clang/Lex/HeaderSearchOptions.h index 41a7ca915d794..3af49e1753956 100644 --- a/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/clang/include/clang/Lex/HeaderSearchOptions.h @@ -94,14 +94,125 @@ class HeaderSearchOptions { : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {} }; - using PrebuiltModuleFilesTy = std::map>; + /// If non-empty, the directory to use as a "virtual system root" for include + /// paths. + std::string Sysroot; + + /// User specified include entries. + std::vector UserEntries; + + /// User-specified system header prefixes. + std::vector SystemHeaderPrefixes; + + /// The directory which holds the compiler resource files (builtin includes, + /// etc.). + std::string ResourceDir; - using ModulesIgnoreMacrosTy = - llvm::SmallSetVector; + /// The directory used for the module cache. + std::string ModuleCachePath; + + /// The directory used for a user build. + std::string ModuleUserBuildPath; + + /// The mapping of module names to prebuilt module files. + std::map> PrebuiltModuleFiles; + + /// The directories used to load prebuilt module files. + std::vector PrebuiltModulePaths; + + /// The module/pch container format. + std::string ModuleFormat; + + /// Whether we should disable the use of the hash string within the + /// module cache. + /// + /// Note: Only used for testing! + unsigned DisableModuleHash : 1; + + /// Implicit module maps. This option is enabld by default when + /// modules is enabled. + unsigned ImplicitModuleMaps : 1; + + /// Set the 'home directory' of a module map file to the current + /// working directory (or the home directory of the module map file that + /// contained the 'extern module' directive importing this module map file + /// if any) rather than the directory containing the module map file. + // + /// The home directory is where we look for files named in the module map + /// file. + unsigned ModuleMapFileHomeIsCwd : 1; + + /// The interval (in seconds) between pruning operations. + /// + /// This operation is expensive, because it requires Clang to walk through + /// the directory structure of the module cache, stat()'ing and removing + /// files. + /// + /// The default value is large, e.g., the operation runs once a week. + unsigned ModuleCachePruneInterval = 7 * 24 * 60 * 60; + + /// The time (in seconds) after which an unused module file will be + /// considered unused and will, therefore, be pruned. + /// + /// When the module cache is pruned, any module file that has not been + /// accessed in this many seconds will be removed. The default value is + /// large, e.g., a month, to avoid forcing infrequently-used modules to be + /// regenerated often. + unsigned ModuleCachePruneAfter = 31 * 24 * 60 * 60; + + /// The time in seconds when the build session started. + /// + /// This time is used by other optimizations in header search and module + /// loading. + uint64_t BuildSessionTimestamp = 0; + + /// The set of macro names that should be ignored for the purposes + /// of computing the module hash. + llvm::SmallSetVector ModulesIgnoreMacros; + + /// The set of user-provided virtual filesystem overlay files. + std::vector VFSOverlayFiles; + + /// Include the compiler builtin includes. + unsigned UseBuiltinIncludes : 1; + + /// Include the system standard include search directories. + unsigned UseStandardSystemIncludes : 1; + + /// Include the system standard C++ library include search directories. + unsigned UseStandardCXXIncludes : 1; + + /// Use libc++ instead of the default libstdc++. + unsigned UseLibcxx : 1; + + /// Whether header search information should be output as for -v. + unsigned Verbose : 1; + + /// If true, skip verifying input files used by modules if the + /// module was already verified during this build session (see + /// \c BuildSessionTimestamp). + unsigned ModulesValidateOncePerBuildSession : 1; + + /// Whether to validate system input files when a module is loaded. + unsigned ModulesValidateSystemHeaders : 1; -#define HEADERSEARCHOPT(Name, Bits, Description) unsigned Name : Bits; -#define TYPED_HEADERSEARCHOPT(Type, Name, Description) Type Name; -#include "clang/Lex/HeaderSearchOptions.def" + // Whether the content of input files should be hashed and used to + // validate consistency. + unsigned ValidateASTInputFilesContent : 1; + + /// Whether the module includes debug information (-gmodules). + unsigned UseDebugInfo : 1; + + unsigned ModulesValidateDiagnosticOptions : 1; + + unsigned ModulesHashContent : 1; + + /// Whether we should include all things that could impact the module in the + /// hash. + /// + /// This includes things like the full header search path, and enabled + /// diagnostics. + unsigned ModulesStrictContextHash : 1; HeaderSearchOptions(StringRef _Sysroot = "/") : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false), @@ -112,9 +223,7 @@ class HeaderSearchOptions { ModulesValidateSystemHeaders(false), ValidateASTInputFilesContent(false), UseDebugInfo(false), ModulesValidateDiagnosticOptions(true), ModulesHashContent(false), - ModulesStrictContextHash(false), - ModuleCachePruneInterval(7 * 24 * 60 * 60), - ModuleCachePruneAfter(31 * 24 * 60 * 60), BuildSessionTimestamp(0) {} + ModulesStrictContextHash(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. void AddPath(StringRef Path, frontend::IncludeDirGroup Group, diff --git a/clang/include/clang/Lex/PreprocessorOptions.def b/clang/include/clang/Lex/PreprocessorOptions.def deleted file mode 100644 index 5b9e982351a0d..0000000000000 --- a/clang/include/clang/Lex/PreprocessorOptions.def +++ /dev/null @@ -1,166 +0,0 @@ -//===--- PreprocessorOptions.def - Preprocessor option database -*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the preprocessor options. Users of this file must -// define the TYPED_PREPROCESSOROPT macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_PREPROCESSOROPT -#error Define the TYPED_PREPROCESSOROPT macro to handle target options -#endif - -TYPED_PREPROCESSOROPT(MacrosTy, Macros, "") - -TYPED_PREPROCESSOROPT(std::vector, Includes, "") - -TYPED_PREPROCESSOROPT(std::vector, MacroIncludes, "") - -TYPED_PREPROCESSOROPT( - bool, UsePredefines, - "Initialize the preprocessor with the compiler and target " - "specific predefines.") - -TYPED_PREPROCESSOROPT( - bool, DetailedRecord, - "Whether we should maintain a detailed record of all macro " - "definitions and expansions.") - -TYPED_PREPROCESSOROPT( - bool, PCHWithHdrStop, - "When true, we are creating or using a PCH where a #pragma hdrstop is " - "expected to indicate the beginning or end of the PCH.") - -TYPED_PREPROCESSOROPT( - bool, PCHWithHdrStopCreate, - "When true, we are creating a PCH or creating the PCH object " - "while expecting a #pragma hdrstop to separate the two. Allow " - "for a missing #pragma hdrstop, which generates a PCH for the " - "whole file, and creates an empty PCH object.") - -TYPED_PREPROCESSOROPT( - std::string, PCHThroughHeader, - "If non-empty, the filename used in an #include directive in the primary " - "source file (or command-line preinclude) that is used to implement " - "MSVC-style precompiled headers. When creating a PCH, after the #include " - "of this header, the PCH generation stops. When using a PCH, tokens are " - "skipped until after an #include of this header is seen.") - -TYPED_PREPROCESSOROPT( - std::string, ImplicitPCHInclude, - "The implicit PCH included at the start of the translation unit, or empty.") - -TYPED_PREPROCESSOROPT( - std::vector, ChainedIncludes, - "Headers that will be converted to chained PCHs in memory.") - -TYPED_PREPROCESSOROPT( - bool, DisablePCHValidation, - "When true, disables most of the normal validation performed " - "on precompiled headers.") - -TYPED_PREPROCESSOROPT( - bool, AllowPCHWithCompilerErrors, - "When true, a PCH with compiler errors will not be rejected.") - -TYPED_PREPROCESSOROPT( - bool, DumpDeserializedPCHDecls, - "Dump declarations that are deserialized from PCH, for testing.") - -TYPED_PREPROCESSOROPT( - std::set, DeserializedPCHDeclsToErrorOn, - "This is a set of names for decls that we do not want to be deserialized, " - "and we emit an error if they are; for testing purposes.") - -TYPED_PREPROCESSOROPT( - PrecompiledPreambleBytesTy, PrecompiledPreambleBytes, - "If non-zero, the implicit PCH include is actually a precompiled preamble " - "that covers this number of bytes in the main source file. The boolean " - "indicates whether the preamble ends at the start of a new line.") - -TYPED_PREPROCESSOROPT( - bool, GeneratePreamble, - "True indicates that a preamble is being generated. When the " - "lexer is done, one of the things that need to be preserved is " - "the conditional #if stack, so the ASTWriter/ASTReader can " - "save/restore it when processing the rest of the file.") - -TYPED_PREPROCESSOROPT( - bool, WriteCommentListToPCH, - "Whether to write comment locations into the PCH when building " - "it. Reading the comments from the PCH can be a performance " - "hit even if the clients don't use them.") - -TYPED_PREPROCESSOROPT( - bool, SingleFileParseMode, - "When enabled, preprocessor is in a mode for parsing a single " - "file only. Disables #includes of other files and if there are " - "unresolved identifiers in preprocessor directive conditions " - "it causes all blocks to be parsed so that the client can get " - "the maximum amount of information from the parser.") - -TYPED_PREPROCESSOROPT( - bool, LexEditorPlaceholders, - "When enabled, the preprocessor will construct editor placeholder tokens.") - -TYPED_PREPROCESSOROPT( - bool, RemappedFilesKeepOriginalName, - "True if the SourceManager should report the original file name for " - "contents of files that were remapped to other files. Defaults to true.") - -TYPED_PREPROCESSOROPT( - RemappedFilesTy, RemappedFiles, - "The set of file remappings, which take existing files on the system (the " - "first part of each pair) and gives them the contents of other files on " - "the system (the second part of each pair).") - -TYPED_PREPROCESSOROPT( - RemappedFileBuffersTy, RemappedFileBuffers, - "The set of file-to-buffer remappings, which take existing files on the " - "system (the first part of each pair) and gives them the contents of the " - "specified memory buffer (the second part of each pair).") - -TYPED_PREPROCESSOROPT( - bool, RetainRemappedFileBuffers, - "Whether the compiler instance should retain (i.e., not free) " - "the buffers associated with remapped files. This flag " - "defaults to false; it can be set true only through direct " - "manipulation of the compiler invocation object, in cases " - "where the compiler invocation and its buffers will be reused.") - -TYPED_PREPROCESSOROPT( - bool, RetainExcludedConditionalBlocks, - "When enabled, excluded conditional blocks retain in the main file.") - -TYPED_PREPROCESSOROPT( - ObjCXXARCStandardLibraryKind, ObjCXXARCStandardLibrary, - "The Objective-C++ ARC standard library that we should support, by " - "providing appropriate definitions to retrofit the standard library with " - "support for lifetime-qualified pointers.") - -TYPED_PREPROCESSOROPT(std::shared_ptr, FailedModules, "") - -TYPED_PREPROCESSOROPT(MacroPrefixMapTy, MacroPrefixMap, - "A prefix map for __FILE__ and __BASE_FILE__.") - -TYPED_PREPROCESSOROPT( - ExcludedPreprocessorDirectiveSkipMapping *, - ExcludedConditionalDirectiveSkipMappings, - "Contains the currently active skipped range mappings for " - "skipping excluded conditional directives. The pointer is " - "passed to the Preprocessor when it's constructed. The pointer " - "is unowned, the client is responsible for its lifetime.") - -TYPED_PREPROCESSOROPT(bool, SetUpStaticAnalyzer, - "Set up preprocessor for RunAnalysis action.") - -TYPED_PREPROCESSOROPT( - bool, DisablePragmaDebugCrash, - "Prevents intended crashes when using #pragma clang __debug. For testing.") - -#undef TYPED_PREPROCESSOROPT diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h index f379d50532287..c551f87e0d7bf 100644 --- a/clang/include/clang/Lex/PreprocessorOptions.h +++ b/clang/include/clang/Lex/PreprocessorOptions.h @@ -44,13 +44,114 @@ enum ObjCXXARCStandardLibraryKind { /// used in preprocessor initialization to InitializePreprocessor(). class PreprocessorOptions { public: - using MacrosTy = std::vector>; - using PrecompiledPreambleBytesTy = std::pair; - using RemappedFilesTy = std::vector>; - using RemappedFileBuffersTy = - std::vector>; - using MacroPrefixMapTy = - std::map>; + std::vector> Macros; + std::vector Includes; + std::vector MacroIncludes; + + /// Initialize the preprocessor with the compiler and target specific + /// predefines. + bool UsePredefines = true; + + /// Whether we should maintain a detailed record of all macro + /// definitions and expansions. + bool DetailedRecord = false; + + /// When true, we are creating or using a PCH where a #pragma hdrstop is + /// expected to indicate the beginning or end of the PCH. + bool PCHWithHdrStop = false; + + /// When true, we are creating a PCH or creating the PCH object while + /// expecting a #pragma hdrstop to separate the two. Allow for a + /// missing #pragma hdrstop, which generates a PCH for the whole file, + /// and creates an empty PCH object. + bool PCHWithHdrStopCreate = false; + + /// If non-empty, the filename used in an #include directive in the primary + /// source file (or command-line preinclude) that is used to implement + /// MSVC-style precompiled headers. When creating a PCH, after the #include + /// of this header, the PCH generation stops. When using a PCH, tokens are + /// skipped until after an #include of this header is seen. + std::string PCHThroughHeader; + + /// The implicit PCH included at the start of the translation unit, or empty. + std::string ImplicitPCHInclude; + + /// Headers that will be converted to chained PCHs in memory. + std::vector ChainedIncludes; + + /// When true, disables most of the normal validation performed on + /// precompiled headers. + bool DisablePCHValidation = false; + + /// When true, a PCH with compiler errors will not be rejected. + bool AllowPCHWithCompilerErrors = false; + + /// Dump declarations that are deserialized from PCH, for testing. + bool DumpDeserializedPCHDecls = false; + + /// This is a set of names for decls that we do not want to be + /// deserialized, and we emit an error if they are; for testing purposes. + std::set DeserializedPCHDeclsToErrorOn; + + /// If non-zero, the implicit PCH include is actually a precompiled + /// preamble that covers this number of bytes in the main source file. + /// + /// The boolean indicates whether the preamble ends at the start of a new + /// line. + std::pair PrecompiledPreambleBytes; + + /// True indicates that a preamble is being generated. + /// + /// When the lexer is done, one of the things that need to be preserved is the + /// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when + /// processing the rest of the file. + bool GeneratePreamble = false; + + /// Whether to write comment locations into the PCH when building it. + /// Reading the comments from the PCH can be a performance hit even if the + /// clients don't use them. + bool WriteCommentListToPCH = true; + + /// When enabled, preprocessor is in a mode for parsing a single file only. + /// + /// Disables #includes of other files and if there are unresolved identifiers + /// in preprocessor directive conditions it causes all blocks to be parsed so + /// that the client can get the maximum amount of information from the parser. + bool SingleFileParseMode = false; + + /// When enabled, the preprocessor will construct editor placeholder tokens. + bool LexEditorPlaceholders = true; + + /// True if the SourceManager should report the original file name for + /// contents of files that were remapped to other files. Defaults to true. + bool RemappedFilesKeepOriginalName = true; + + /// The set of file remappings, which take existing files on + /// the system (the first part of each pair) and gives them the + /// contents of other files on the system (the second part of each + /// pair). + std::vector> RemappedFiles; + + /// The set of file-to-buffer remappings, which take existing files + /// on the system (the first part of each pair) and gives them the contents + /// of the specified memory buffer (the second part of each pair). + std::vector> RemappedFileBuffers; + + /// Whether the compiler instance should retain (i.e., not free) + /// the buffers associated with remapped files. + /// + /// This flag defaults to false; it can be set true only through direct + /// manipulation of the compiler invocation object, in cases where the + /// compiler invocation and its buffers will be reused. + bool RetainRemappedFileBuffers = false; + + /// When enabled, excluded conditional blocks retain in the main file. + bool RetainExcludedConditionalBlocks = false; + + /// The Objective-C++ ARC standard library that we should support, + /// by providing appropriate definitions to retrofit the standard library + /// with support for lifetime-qualified pointers. + ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib; /// Records the set of modules class FailedModulesSet { @@ -66,21 +167,33 @@ class PreprocessorOptions { } }; -#define TYPED_PREPROCESSOROPT(Type, Name, Description) Type Name; -#include "clang/Lex/PreprocessorOptions.def" - - PreprocessorOptions() - : UsePredefines(true), DetailedRecord(false), PCHWithHdrStop(false), - PCHWithHdrStopCreate(false), DisablePCHValidation(false), - AllowPCHWithCompilerErrors(false), DumpDeserializedPCHDecls(false), - PrecompiledPreambleBytes(0, false), GeneratePreamble(false), - WriteCommentListToPCH(true), SingleFileParseMode(false), - LexEditorPlaceholders(true), RemappedFilesKeepOriginalName(true), - RetainRemappedFileBuffers(false), - RetainExcludedConditionalBlocks(false), - ObjCXXARCStandardLibrary(ARCXX_nolib), - ExcludedConditionalDirectiveSkipMappings(nullptr), - SetUpStaticAnalyzer(false), DisablePragmaDebugCrash(false) {} + /// The set of modules that failed to build. + /// + /// This pointer will be shared among all of the compiler instances created + /// to (re)build modules, so that once a module fails to build anywhere, + /// other instances will see that the module has failed and won't try to + /// build it again. + std::shared_ptr FailedModules; + + /// A prefix map for __FILE__ and __BASE_FILE__. + std::map> MacroPrefixMap; + + /// Contains the currently active skipped range mappings for skipping excluded + /// conditional directives. + /// + /// The pointer is passed to the Preprocessor when it's constructed. The + /// pointer is unowned, the client is responsible for its lifetime. + ExcludedPreprocessorDirectiveSkipMapping + *ExcludedConditionalDirectiveSkipMappings = nullptr; + + /// Set up preprocessor for RunAnalysis action. + bool SetUpStaticAnalyzer = false; + + /// Prevents intended crashes when using #pragma clang __debug. For testing. + bool DisablePragmaDebugCrash = false; + +public: + PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {} void addMacroDef(StringRef Name) { Macros.emplace_back(std::string(Name), false); diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index dfa4d7e1f2a12..66f22732e29cd 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -202,7 +202,8 @@ class Parser : public CodeCompletionHandler { std::unique_ptr UnrollAndJamHintHandler; std::unique_ptr NoUnrollAndJamHintHandler; std::unique_ptr FPHandler; - std::unique_ptr STDCFENVHandler; + std::unique_ptr STDCFenvAccessHandler; + std::unique_ptr STDCFenvRoundHandler; std::unique_ptr STDCCXLIMITHandler; std::unique_ptr STDCUnknownHandler; std::unique_ptr AttributePragmaHandler; @@ -745,6 +746,10 @@ class Parser : public CodeCompletionHandler { /// #pragma STDC FENV_ACCESS... void HandlePragmaFEnvAccess(); + /// Handle the annotation token produced for + /// #pragma STDC FENV_ROUND... + void HandlePragmaFEnvRound(); + /// Handle the annotation token produced for /// #pragma float_control void HandlePragmaFloatControl(); diff --git a/clang/include/clang/Sema/CodeCompleteOptions.def b/clang/include/clang/Sema/CodeCompleteOptions.def deleted file mode 100644 index dab8027929e5e..0000000000000 --- a/clang/include/clang/Sema/CodeCompleteOptions.def +++ /dev/null @@ -1,51 +0,0 @@ -//===--- CodeCompleteOptions.def - FileSystem option database ----*- C++-*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the CodeComplete options. -// -//===----------------------------------------------------------------------===// - -#ifndef TYPED_CODE_COMPLETEOPT -#define TYPED_CODE_COMPLETEOPT(Type, Name, Description) -#endif - -#ifndef CODE_COMPLETEOPT -#define CODE_COMPLETEOPT(Name, Bits, Description) \ - TYPED_CODE_COMPLETEOPT(unsigned, Name, Description); -#endif - -CODE_COMPLETEOPT(IncludeMacros, 1, "Show macros in code completion results.") - -CODE_COMPLETEOPT(IncludeCodePatterns, 1, - "Show code patterns in code completion results.") - -CODE_COMPLETEOPT(IncludeGlobals, 1, - "Show top-level decls in code completion results.") - -CODE_COMPLETEOPT(IncludeNamespaceLevelDecls, 1, - "Show decls in namespace (including the global namespace) in " - "code completion results. If this is 0, `IncludeGlobals` will " - "be ignored. Currently, this only works when completing " - "qualified IDs (i.e. `Sema::CodeCompleteQualifiedId`). FIXME: " - "consider supporting more completion cases with this option.") - -CODE_COMPLETEOPT( - IncludeBriefComments, 1, - "Show brief documentation comments in code completion results.") - -CODE_COMPLETEOPT(LoadExternal, 1, - "Hint whether to load data from the external AST to provide " - "full results. If false, namespace-level declarations and " - "macros from the preamble may be omitted.") - -CODE_COMPLETEOPT(IncludeFixIts, 1, - "Include results after corrections (small fix-its), e.g. " - "change '.' to '->' on member access, etc.") - -#undef TYPED_CODE_COMPLETEOPT -#undef CODE_COMPLETEOPT \ No newline at end of file diff --git a/clang/include/clang/Sema/CodeCompleteOptions.h b/clang/include/clang/Sema/CodeCompleteOptions.h index 28cbc94fc84c2..a3403b01dcde9 100644 --- a/clang/include/clang/Sema/CodeCompleteOptions.h +++ b/clang/include/clang/Sema/CodeCompleteOptions.h @@ -14,14 +14,39 @@ namespace clang { /// Options controlling the behavior of code completion. class CodeCompleteOptions { public: -#define CODE_COMPLETEOPT(Name, Bits, Description) unsigned Name : Bits; -#define TYPED_CODE_COMPLETEOPT(Type, Name, Description) Type Name; -#include "clang/Sema/CodeCompleteOptions.def" + /// Show macros in code completion results. + unsigned IncludeMacros : 1; + + /// Show code patterns in code completion results. + unsigned IncludeCodePatterns : 1; + + /// Show top-level decls in code completion results. + unsigned IncludeGlobals : 1; + + /// Show decls in namespace (including the global namespace) in code + /// completion results. If this is 0, `IncludeGlobals` will be ignored. + /// + /// Currently, this only works when completing qualified IDs (i.e. + /// `Sema::CodeCompleteQualifiedId`). + /// FIXME: consider supporting more completion cases with this option. + unsigned IncludeNamespaceLevelDecls : 1; + + /// Show brief documentation comments in code completion results. + unsigned IncludeBriefComments : 1; + + /// Hint whether to load data from the external AST to provide full results. + /// If false, namespace-level declarations and macros from the preamble may be + /// omitted. + unsigned LoadExternal : 1; + + /// Include results after corrections (small fix-its), e.g. change '.' to '->' + /// on member access, etc. + unsigned IncludeFixIts : 1; CodeCompleteOptions() : IncludeMacros(0), IncludeCodePatterns(0), IncludeGlobals(1), - IncludeNamespaceLevelDecls(1), IncludeBriefComments(0), LoadExternal(1), - IncludeFixIts(0) {} + IncludeNamespaceLevelDecls(1), IncludeBriefComments(0), + LoadExternal(1), IncludeFixIts(0) {} }; } // namespace clang diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 9b25973ba77ec..af8ddf40ff12a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9904,7 +9904,7 @@ class Sema final { /// \#pragma STDC FENV_ACCESS void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled); - /// Called to set rounding mode for floating point operations. + /// Called to set constant rounding mode for floating point operations. void setRoundingMode(SourceLocation Loc, llvm::RoundingMode); /// Called to set exception behavior for floating point operations. @@ -9986,7 +9986,9 @@ class Sema final { Expr *E); void AddIntelFPGABankBitsAttr(Decl *D, const AttributeCommonInfo &CI, Expr **Exprs, unsigned Size); - + template + void addIntelSYCLSingleArgFunctionAttr(Decl *D, const AttributeCommonInfo &CI, + Expr *E); /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, bool IsPackExpansion); @@ -10041,10 +10043,6 @@ class Sema final { bool checkAllowedSYCLInitializer(VarDecl *VD, bool CheckValueDependent = false); - // Adds an intel_reqd_sub_group_size attribute to a particular declaration. - void addIntelReqdSubGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, - Expr *E); - //===--------------------------------------------------------------------===// // C++ Coroutines TS // @@ -11400,10 +11398,6 @@ class Sema final { ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit = false); - ExprResult PerformImplicitConversion(Expr *From, QualType ToType, - AssignmentAction Action, - bool AllowExplicit, - ImplicitConversionSequence& ICS); ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence& ICS, AssignmentAction Action, @@ -12840,6 +12834,31 @@ class Sema final { } }; +template +void Sema::addIntelSYCLSingleArgFunctionAttr(Decl *D, + const AttributeCommonInfo &CI, + Expr *E) { + assert(E && "Attribute must have an argument."); + + if (!E->isInstantiationDependent()) { + Optional ArgVal = E->getIntegerConstantExpr(getASTContext()); + if (!ArgVal) { + Diag(E->getExprLoc(), diag::err_attribute_argument_type) + << CI.getAttrName() << AANT_ArgumentIntegerConstant + << E->getSourceRange(); + return; + } + int32_t ArgInt = ArgVal->getSExtValue(); + if (ArgInt <= 0) { + Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) + << CI.getAttrName() << /*positive*/ 0; + return; + } + } + + D->addAttr(::new (Context) AttrType(Context, CI, E)); +} + template void Sema::AddOneConstantValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) { diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index b6892e295ac7c..29c4f15e57b09 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -900,8 +900,9 @@ class ASTReader /// Delete expressions to analyze at the end of translation unit. SmallVector DelayedDeleteExprs; - // A list of late parsed template function data. - SmallVector LateParsedTemplates; + // A list of late parsed template function data with their module files. + SmallVector>, 4> + LateParsedTemplates; /// The IDs of all decls to be checked for deferred diags. /// diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index a444843c50060..a61af45231348 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -349,7 +349,6 @@ let ParentPackage = APIModeling in { def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">, HelpText<"Improve modeling of the C standard library functions">, - Dependencies<[CallAndMessageModeling]>, CheckerOptions<[ CmdLineOption, "such as whether the parameter of isalpha is in the range [0, 255] " "or is EOF.">, Dependencies<[StdCLibraryFunctionsChecker]>, - WeakDependencies<[NonNullParamChecker]>, + WeakDependencies<[CallAndMessageChecker, NonNullParamChecker, StreamChecker]>, Documentation; } // end "alpha.unix" diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index ff253ca15c0ea..f0359d2dbb3c2 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -6,10 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines the analyzer options avaible with -analyzer-config, using -// the ANLAYZER_OPTION and ANALYZER_OPTION_DEPENDS_ON_USER_MODE macros. -// Other analyzer options use the simpler ANALYZEROPT and TYPED_ANALYZEROPT -// macro. +// This file defines the analyzer options avaible with -analyzer-config. // //===----------------------------------------------------------------------===// @@ -32,15 +29,6 @@ define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' macros! #endif #endif -#ifndef TYPED_ANALYZEROPT -#define TYPED_ANALYZEROPT(TYPE, NAME, DESCRIPTION) -#endif - -#ifndef ANALYZEROPT -#define ANALYZEROPT(NAME, BITS, DESCRIPTION) \ - TYPED_ANALYZEROPT(unsigned, NAME, DESCRITPTION) -#endif - #ifndef ANALYZER_OPTION /// Create a new analyzer option, but dont generate a method for it in /// AnalyzerOptions. @@ -54,8 +42,7 @@ define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' macros! /// (-analyzer-config CMDFLAG=VALUE) /// DESC - Description of the flag. /// DEFAULT_VAL - The default value for CMDFLAG. -#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ - TYPED_ANALYZEROPT(TYPE, NAME, DESC) +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) #endif #ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE @@ -75,8 +62,7 @@ define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' macros! /// DEEP_VAL - The default value for CMDFLAG, when "user-mode" was set to /// "deep". #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \ - SHALLOW_VAL, DEEP_VAL) \ - TYPED_ANALYZEROPT(TYPE, NAME, DESC) + SHALLOW_VAL, DEEP_VAL) #endif //===----------------------------------------------------------------------===// @@ -449,79 +435,5 @@ ANALYZER_OPTION_DEPENDS_ON_USER_MODE( "\"basic-inlining\", \"inlining\", \"dynamic\", \"dynamic-bifurcate\".", /* SHALLOW_VAL */ "inlining", /* DEEP_VAL */ "dynamic-bifurcate") -//===----------------------------------------------------------------------===// -// Other analyzer options. -//===----------------------------------------------------------------------===// - -TYPED_ANALYZEROPT(CheckersAndPackagesTy, CheckersAndPackages, - "Pairs of checker/package name and enable/disable.") - -TYPED_ANALYZEROPT( - std::vector, SilencedCheckersAndPackages, - "Vector of checker/package names which will not emit warnings.") - -TYPED_ANALYZEROPT(ConfigTable, Config, - "A key-value table of use-specified configuration values.") -TYPED_ANALYZEROPT(AnalysisStores, AnalysisStoreOpt, "") -TYPED_ANALYZEROPT(AnalysisConstraints, AnalysisConstraintsOpt, "") -TYPED_ANALYZEROPT(AnalysisDiagClients, AnalysisDiagOpt, "") -TYPED_ANALYZEROPT(AnalysisPurgeMode, AnalysisPurgeOpt, "") - -TYPED_ANALYZEROPT(std::string, AnalyzeSpecificFunction, "") - -TYPED_ANALYZEROPT(std::string, DumpExplodedGraphTo, - "File path to which the exploded graph should be dumped.") - -TYPED_ANALYZEROPT(std::string, FullCompilerInvocation, - "Store full compiler invocation for reproducible " - "instructions in the generated report.") - -TYPED_ANALYZEROPT(unsigned, maxBlockVisitOnPath, - "The maximum number of times the analyzer visits a block.") - -ANALYZEROPT( - DisableAllCheckers, 1, - "Disable all analyzer checkers. This flag allows one to disable analyzer " - "checkers on the code processed by the given analysis consumer. Note, the " - "code will get parsed and the command-line options will get checked.") - -ANALYZEROPT(ShowCheckerHelp, 1, "") -ANALYZEROPT(ShowCheckerHelpAlpha, 1, "") -ANALYZEROPT(ShowCheckerHelpDeveloper, 1, "") - -ANALYZEROPT(ShowCheckerOptionList, 1, "") -ANALYZEROPT(ShowCheckerOptionAlphaList, 1, "") -ANALYZEROPT(ShowCheckerOptionDeveloperList, 1, "") - -ANALYZEROPT(ShowEnabledCheckerList, 1, "") -ANALYZEROPT(ShowConfigOptionsList, 1, "") -ANALYZEROPT(ShouldEmitErrorsOnInvalidConfigValue, 1, "") -ANALYZEROPT(AnalyzeAll, 1, "") -ANALYZEROPT(AnalyzerDisplayProgress, 1, "") -ANALYZEROPT(AnalyzeNestedBlocks, 1, "") - -ANALYZEROPT(eagerlyAssumeBinOpBifurcation, 1, "") - -ANALYZEROPT(TrimGraph, 1, "") -ANALYZEROPT(visualizeExplodedGraphWithGraphViz, 1, "") -ANALYZEROPT(UnoptimizedCFG, 1, "") -ANALYZEROPT(PrintStats, 1, "") - -ANALYZEROPT( - NoRetryExhausted, 1, - "Do not re-analyze paths leading to exhausted nodes with a different " - "strategy. We get better code coverage when retry is enabled.") - -ANALYZEROPT(AnalyzerWerror, 1, "Emit analyzer warnings as errors.") - -TYPED_ANALYZEROPT(unsigned, InlineMaxStackDepth, - "The inlining stack depth limit. Cap the stack depth at 4 " - "calls (5 stack frames, base + 4 calls).") - -TYPED_ANALYZEROPT(AnalysisInliningMode, InliningMode, - "The mode of function selection used during inlining.") - #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE #undef ANALYZER_OPTION -#undef TYPED_ANALYZEROPT -#undef ANALYZEROPT diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 8d81f90294174..4907b0757a8a4 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -162,7 +162,6 @@ enum UserModeKind { class AnalyzerOptions : public RefCountedBase { public: using ConfigTable = llvm::StringMap; - using CheckersAndPackagesTy = std::vector>; /// Retrieves the list of checkers generated from Checkers.td. This doesn't /// contain statically linked but non-generated checkers and plugin checkers! @@ -196,9 +195,86 @@ class AnalyzerOptions : public RefCountedBase { size_t InitialPad, size_t EntryWidth, size_t MinLineWidth = 0); -#define ANALYZEROPT(NAME, BITS, DESCRIPTION) unsigned NAME : BITS; -#define TYPED_ANALYZEROPT(TYPE, NAME, DESCRIPTION) TYPE NAME; + /// Pairs of checker/package name and enable/disable. + std::vector> CheckersAndPackages; + + /// Vector of checker/package names which will not emit warnings. + std::vector SilencedCheckersAndPackages; + + /// A key-value table of use-specified configuration values. + // TODO: This shouldn't be public. + ConfigTable Config; + AnalysisStores AnalysisStoreOpt = RegionStoreModel; + AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel; + AnalysisDiagClients AnalysisDiagOpt = PD_HTML; + AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt; + + std::string AnalyzeSpecificFunction; + + /// File path to which the exploded graph should be dumped. + std::string DumpExplodedGraphTo; + + /// Store full compiler invocation for reproducible instructions in the + /// generated report. + std::string FullCompilerInvocation; + + /// The maximum number of times the analyzer visits a block. + unsigned maxBlockVisitOnPath; + + /// Disable all analyzer checkers. + /// + /// This flag allows one to disable analyzer checkers on the code processed by + /// the given analysis consumer. Note, the code will get parsed and the + /// command-line options will get checked. + unsigned DisableAllCheckers : 1; + + unsigned ShowCheckerHelp : 1; + unsigned ShowCheckerHelpAlpha : 1; + unsigned ShowCheckerHelpDeveloper : 1; + + unsigned ShowCheckerOptionList : 1; + unsigned ShowCheckerOptionAlphaList : 1; + unsigned ShowCheckerOptionDeveloperList : 1; + + unsigned ShowEnabledCheckerList : 1; + unsigned ShowConfigOptionsList : 1; + unsigned ShouldEmitErrorsOnInvalidConfigValue : 1; + unsigned AnalyzeAll : 1; + unsigned AnalyzerDisplayProgress : 1; + unsigned AnalyzeNestedBlocks : 1; + + unsigned eagerlyAssumeBinOpBifurcation : 1; + + unsigned TrimGraph : 1; + unsigned visualizeExplodedGraphWithGraphViz : 1; + unsigned UnoptimizedCFG : 1; + unsigned PrintStats : 1; + + /// Do not re-analyze paths leading to exhausted nodes with a different + /// strategy. We get better code coverage when retry is enabled. + unsigned NoRetryExhausted : 1; + + /// Emit analyzer warnings as errors. + unsigned AnalyzerWerror : 1; + + /// The inlining stack depth limit. + // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls). + unsigned InlineMaxStackDepth = 5; + + /// The mode of function selection used during inlining. + AnalysisInliningMode InliningMode = NoRedundancy; + + // Create a field for each -analyzer-config option. +#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \ + SHALLOW_VAL, DEEP_VAL) \ + ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL) + +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ + TYPE NAME; + #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" +#undef ANALYZER_OPTION +#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE // Create an array of all -analyzer-config command line options. Sort it in // the constructor. @@ -223,19 +299,15 @@ class AnalyzerOptions : public RefCountedBase { } AnalyzerOptions() - : AnalysisStoreOpt(RegionStoreModel), - AnalysisConstraintsOpt(RangeConstraintsModel), AnalysisDiagOpt(PD_HTML), - AnalysisPurgeOpt(PurgeStmt), DisableAllCheckers(false), - ShowCheckerHelp(false), ShowCheckerHelpAlpha(false), - ShowCheckerHelpDeveloper(false), ShowCheckerOptionList(false), - ShowCheckerOptionAlphaList(false), + : DisableAllCheckers(false), ShowCheckerHelp(false), + ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false), + ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false), ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false), ShowConfigOptionsList(false), AnalyzeAll(false), AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false), eagerlyAssumeBinOpBifurcation(false), TrimGraph(false), visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false), - PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false), - InlineMaxStackDepth(5), InliningMode(NoRedundancy) { + PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) { llvm::sort(AnalyzerConfigCmdFlags); } diff --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h b/clang/include/clang/Tooling/Transformer/RewriteRule.h index 9700d1ff539de..4bdcc8d5c3296 100644 --- a/clang/include/clang/Tooling/Transformer/RewriteRule.h +++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h @@ -380,6 +380,38 @@ EditGenerator rewriteDescendants(std::string NodeId, RewriteRule Rule); // RewriteRule API. Recast them as such. Or, just declare these functions // public and well-supported and move them out of `detail`. namespace detail { +/// The following overload set is a version of `rewriteDescendants` that +/// operates directly on the AST, rather than generating a Transformer +/// combinator. It applies `Rule` to all descendants of `Node`, although not +/// `Node` itself. `Rule` can refer to nodes bound in `Result`. +/// +/// For example, assuming that "body" is bound to a function body in MatchResult +/// `Results`, this will produce edits to change all appearances of `x` in that +/// body to `3`. +/// ``` +/// auto InlineX = +/// makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3"))); +/// const auto *Node = Results.Nodes.getNodeAs("body"); +/// auto Edits = rewriteDescendants(*Node, InlineX, Results); +/// ``` +/// @{ +llvm::Expected> +rewriteDescendants(const Decl &Node, RewriteRule Rule, + const ast_matchers::MatchFinder::MatchResult &Result); + +llvm::Expected> +rewriteDescendants(const Stmt &Node, RewriteRule Rule, + const ast_matchers::MatchFinder::MatchResult &Result); + +llvm::Expected> +rewriteDescendants(const TypeLoc &Node, RewriteRule Rule, + const ast_matchers::MatchFinder::MatchResult &Result); + +llvm::Expected> +rewriteDescendants(const DynTypedNode &Node, RewriteRule Rule, + const ast_matchers::MatchFinder::MatchResult &Result); +/// @} + /// Builds a single matcher for the rule, covering all of the rule's cases. /// Only supports Rules whose cases' matchers share the same base "kind" /// (`Stmt`, `Decl`, etc.) Deprecated: use `buildMatchers` instead, which diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 2a8834b4db0cb..08ae0ff3c67d3 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -304,6 +304,25 @@ APValue::APValue(const APValue &RHS) : Kind(None) { } } +APValue::APValue(APValue &&RHS) : Kind(RHS.Kind), Data(RHS.Data) { + RHS.Kind = None; +} + +APValue &APValue::operator=(const APValue &RHS) { + if (this != &RHS) + *this = APValue(RHS); + return *this; +} + +APValue &APValue::operator=(APValue &&RHS) { + if (Kind != None && Kind != Indeterminate) + DestroyDataAndMakeUninit(); + Kind = RHS.Kind; + Data = RHS.Data; + RHS.Kind = None; + return *this; +} + void APValue::DestroyDataAndMakeUninit() { if (Kind == Int) ((APSInt*)(char*)Data.buffer)->~APSInt(); @@ -372,10 +391,7 @@ bool APValue::needsCleanup() const { void APValue::swap(APValue &RHS) { std::swap(Kind, RHS.Kind); - char TmpData[DataSize]; - memcpy(TmpData, Data.buffer, DataSize); - memcpy(Data.buffer, RHS.Data.buffer, DataSize); - memcpy(RHS.Data.buffer, TmpData, DataSize); + std::swap(Data, RHS.Data); } static double GetApproxValue(const llvm::APFloat &F) { diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index 35099fd0dacf8..dfd26fd97bc6d 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -55,6 +55,7 @@ add_clang_library(clangAST ExternalASTMerger.cpp ExternalASTSource.cpp FormatString.cpp + IgnoreExpr.cpp InheritViz.cpp Interp/ByteCodeEmitter.cpp Interp/ByteCodeExprGen.cpp diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index b1a8e00f272f2..2a7017635b08c 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1299,7 +1299,8 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, // we should not make static local variables in the function hidden. LV = getLVForDecl(FD, computation); if (isa(D) && useInlineVisibilityHidden(FD) && - !LV.isVisibilityExplicit()) { + !LV.isVisibilityExplicit() && + !Context.getLangOpts().VisibilityInlinesHiddenStaticLocalVar) { assert(cast(D)->isStaticLocal()); // If this was an implicitly hidden inline method, check again for // explicit visibility on the parent class, and use that for static locals diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 8efd6837c541b..15f3df0fd2168 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -21,6 +21,7 @@ #include "clang/AST/DependenceFlags.h" #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/IgnoreExpr.h" #include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtVisitor.h" @@ -39,7 +40,7 @@ using namespace clang; const Expr *Expr::getBestDynamicClassTypeExpr() const { const Expr *E = this; while (true) { - E = E->ignoreParenBaseCasts(); + E = E->IgnoreParenBaseCasts(); // Follow the RHS of a comma operator. if (auto *BO = dyn_cast(E)) { @@ -2779,162 +2780,8 @@ QualType Expr::findBoundMemberType(const Expr *expr) { return QualType(); } -static Expr *IgnoreImpCastsSingleStep(Expr *E) { - if (auto *ICE = dyn_cast(E)) - return ICE->getSubExpr(); - - if (auto *FE = dyn_cast(E)) - return FE->getSubExpr(); - - return E; -} - -static Expr *IgnoreImpCastsExtraSingleStep(Expr *E) { - // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in - // addition to what IgnoreImpCasts() skips to account for the current - // behaviour of IgnoreParenImpCasts(). - Expr *SubE = IgnoreImpCastsSingleStep(E); - if (SubE != E) - return SubE; - - if (auto *MTE = dyn_cast(E)) - return MTE->getSubExpr(); - - if (auto *NTTP = dyn_cast(E)) - return NTTP->getReplacement(); - - return E; -} - -static Expr *IgnoreCastsSingleStep(Expr *E) { - if (auto *CE = dyn_cast(E)) - return CE->getSubExpr(); - - if (auto *FE = dyn_cast(E)) - return FE->getSubExpr(); - - if (auto *MTE = dyn_cast(E)) - return MTE->getSubExpr(); - - if (auto *NTTP = dyn_cast(E)) - return NTTP->getReplacement(); - - return E; -} - -static Expr *IgnoreLValueCastsSingleStep(Expr *E) { - // Skip what IgnoreCastsSingleStep skips, except that only - // lvalue-to-rvalue casts are skipped. - if (auto *CE = dyn_cast(E)) - if (CE->getCastKind() != CK_LValueToRValue) - return E; - - return IgnoreCastsSingleStep(E); -} - -static Expr *IgnoreBaseCastsSingleStep(Expr *E) { - if (auto *CE = dyn_cast(E)) - if (CE->getCastKind() == CK_DerivedToBase || - CE->getCastKind() == CK_UncheckedDerivedToBase || - CE->getCastKind() == CK_NoOp) - return CE->getSubExpr(); - - return E; -} - -static Expr *IgnoreImplicitSingleStep(Expr *E) { - Expr *SubE = IgnoreImpCastsSingleStep(E); - if (SubE != E) - return SubE; - - if (auto *MTE = dyn_cast(E)) - return MTE->getSubExpr(); - - if (auto *BTE = dyn_cast(E)) - return BTE->getSubExpr(); - - return E; -} - -static Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) { - if (auto *ICE = dyn_cast(E)) - return ICE->getSubExprAsWritten(); - - return IgnoreImplicitSingleStep(E); -} - -static Expr *IgnoreParensOnlySingleStep(Expr *E) { - if (auto *PE = dyn_cast(E)) - return PE->getSubExpr(); - return E; -} - -static Expr *IgnoreParensSingleStep(Expr *E) { - if (auto *PE = dyn_cast(E)) - return PE->getSubExpr(); - - if (auto *UO = dyn_cast(E)) { - if (UO->getOpcode() == UO_Extension) - return UO->getSubExpr(); - } - - else if (auto *GSE = dyn_cast(E)) { - if (!GSE->isResultDependent()) - return GSE->getResultExpr(); - } - - else if (auto *CE = dyn_cast(E)) { - if (!CE->isConditionDependent()) - return CE->getChosenSubExpr(); - } - - return E; -} - -static Expr *IgnoreNoopCastsSingleStep(const ASTContext &Ctx, Expr *E) { - if (auto *CE = dyn_cast(E)) { - // We ignore integer <-> casts that are of the same width, ptr<->ptr and - // ptr<->int casts of the same width. We also ignore all identity casts. - Expr *SubExpr = CE->getSubExpr(); - bool IsIdentityCast = - Ctx.hasSameUnqualifiedType(E->getType(), SubExpr->getType()); - bool IsSameWidthCast = - (E->getType()->isPointerType() || E->getType()->isIntegralType(Ctx)) && - (SubExpr->getType()->isPointerType() || - SubExpr->getType()->isIntegralType(Ctx)) && - (Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SubExpr->getType())); - - if (IsIdentityCast || IsSameWidthCast) - return SubExpr; - } - - else if (auto *NTTP = dyn_cast(E)) - return NTTP->getReplacement(); - - return E; -} - -static Expr *IgnoreExprNodesImpl(Expr *E) { return E; } -template -static Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) { - return IgnoreExprNodesImpl(Fn(E), std::forward(Fns)...); -} - -/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, -/// Recursively apply each of the functions to E until reaching a fixed point. -/// Note that a null E is valid; in this case nothing is done. -template -static Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) { - Expr *LastE = nullptr; - while (E != LastE) { - LastE = E; - E = IgnoreExprNodesImpl(E, std::forward(Fns)...); - } - return E; -} - Expr *Expr::IgnoreImpCasts() { - return IgnoreExprNodes(this, IgnoreImpCastsSingleStep); + return IgnoreExprNodes(this, IgnoreImplicitCastsSingleStep); } Expr *Expr::IgnoreCasts() { @@ -2955,14 +2802,14 @@ Expr *Expr::IgnoreParens() { Expr *Expr::IgnoreParenImpCasts() { return IgnoreExprNodes(this, IgnoreParensSingleStep, - IgnoreImpCastsExtraSingleStep); + IgnoreImplicitCastsExtraSingleStep); } Expr *Expr::IgnoreParenCasts() { return IgnoreExprNodes(this, IgnoreParensSingleStep, IgnoreCastsSingleStep); } -Expr *Expr::IgnoreConversionOperator() { +Expr *Expr::IgnoreConversionOperatorSingleStep() { if (auto *MCE = dyn_cast(this)) { if (MCE->getMethodDecl() && isa(MCE->getMethodDecl())) return MCE->getImplicitObjectArgument(); @@ -2975,58 +2822,72 @@ Expr *Expr::IgnoreParenLValueCasts() { IgnoreLValueCastsSingleStep); } -Expr *Expr::ignoreParenBaseCasts() { +Expr *Expr::IgnoreParenBaseCasts() { return IgnoreExprNodes(this, IgnoreParensSingleStep, IgnoreBaseCastsSingleStep); } Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) { - return IgnoreExprNodes(this, IgnoreParensSingleStep, [&Ctx](Expr *E) { - return IgnoreNoopCastsSingleStep(Ctx, E); - }); + auto IgnoreNoopCastsSingleStep = [&Ctx](Expr *E) { + if (auto *CE = dyn_cast(E)) { + // We ignore integer <-> casts that are of the same width, ptr<->ptr and + // ptr<->int casts of the same width. We also ignore all identity casts. + Expr *SubExpr = CE->getSubExpr(); + bool IsIdentityCast = + Ctx.hasSameUnqualifiedType(E->getType(), SubExpr->getType()); + bool IsSameWidthCast = (E->getType()->isPointerType() || + E->getType()->isIntegralType(Ctx)) && + (SubExpr->getType()->isPointerType() || + SubExpr->getType()->isIntegralType(Ctx)) && + (Ctx.getTypeSize(E->getType()) == + Ctx.getTypeSize(SubExpr->getType())); + + if (IsIdentityCast || IsSameWidthCast) + return SubExpr; + } else if (auto *NTTP = dyn_cast(E)) + return NTTP->getReplacement(); + + return E; + }; + return IgnoreExprNodes(this, IgnoreParensSingleStep, + IgnoreNoopCastsSingleStep); } Expr *Expr::IgnoreUnlessSpelledInSource() { - Expr *E = this; - - Expr *LastE = nullptr; - while (E != LastE) { - LastE = E; - E = IgnoreExprNodes(E, IgnoreImplicitSingleStep, - IgnoreImpCastsExtraSingleStep, - IgnoreParensOnlySingleStep); - - auto SR = E->getSourceRange(); - + auto IgnoreImplicitConstructorSingleStep = [](Expr *E) { if (auto *C = dyn_cast(E)) { auto NumArgs = C->getNumArgs(); if (NumArgs == 1 || (NumArgs > 1 && isa(C->getArg(1)))) { Expr *A = C->getArg(0); - if (A->getSourceRange() == SR || !isa(C)) - E = A; + if (A->getSourceRange() == E->getSourceRange() || + !isa(C)) + return A; } } - + return E; + }; + auto IgnoreImplicitMemberCallSingleStep = [](Expr *E) { if (auto *C = dyn_cast(E)) { Expr *ExprNode = C->getImplicitObjectArgument(); - if (ExprNode->getSourceRange() == SR) { - E = ExprNode; - continue; + if (ExprNode->getSourceRange() == E->getSourceRange()) { + return ExprNode; } if (auto *PE = dyn_cast(ExprNode)) { if (PE->getSourceRange() == C->getSourceRange()) { - E = PE; - continue; + return cast(PE); } } ExprNode = ExprNode->IgnoreParenImpCasts(); - if (ExprNode->getSourceRange() == SR) - E = ExprNode; + if (ExprNode->getSourceRange() == E->getSourceRange()) + return ExprNode; } - } - - return E; + return E; + }; + return IgnoreExprNodes( + this, IgnoreImplicitSingleStep, IgnoreImplicitCastsExtraSingleStep, + IgnoreParensOnlySingleStep, IgnoreImplicitConstructorSingleStep, + IgnoreImplicitMemberCallSingleStep); } bool Expr::isDefaultArgument() const { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 1479e87f2a0df..b6083fdc16fcf 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6627,9 +6627,15 @@ class APValueToBufferConverter { } bool visitInt(const APSInt &Val, QualType Ty, CharUnits Offset) { - CharUnits Width = Info.Ctx.getTypeSizeInChars(Ty); - SmallVector Bytes(Width.getQuantity()); - llvm::StoreIntToMemory(Val, &*Bytes.begin(), Width.getQuantity()); + APSInt AdjustedVal = Val; + unsigned Width = AdjustedVal.getBitWidth(); + if (Ty->isBooleanType()) { + Width = Info.Ctx.getTypeSize(Ty); + AdjustedVal = AdjustedVal.extend(Width); + } + + SmallVector Bytes(Width / 8); + llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8); Buffer.writeObject(Offset, Bytes); return true; } @@ -6670,6 +6676,13 @@ class BufferToAPValueConverter { return None; } + llvm::NoneType unrepresentableValue(QualType Ty, const APSInt &Val) { + Info.FFDiag(BCE->getBeginLoc(), + diag::note_constexpr_bit_cast_unrepresentable_value) + << Ty << Val.toString(/*Radix=*/10); + return None; + } + Optional visit(const BuiltinType *T, CharUnits Offset, const EnumType *EnumSugar = nullptr) { if (T->isNullPtrType()) { @@ -6680,6 +6693,20 @@ class BufferToAPValueConverter { } CharUnits SizeOf = Info.Ctx.getTypeSizeInChars(T); + + // Work around floating point types that contain unused padding bytes. This + // is really just `long double` on x86, which is the only fundamental type + // with padding bytes. + if (T->isRealFloatingType()) { + const llvm::fltSemantics &Semantics = + Info.Ctx.getFloatTypeSemantics(QualType(T, 0)); + unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics); + assert(NumBits % 8 == 0); + CharUnits NumBytes = CharUnits::fromQuantity(NumBits / 8); + if (NumBytes != SizeOf) + SizeOf = NumBytes; + } + SmallVector Bytes; if (!Buffer.readObject(Offset, SizeOf, Bytes)) { // If this is std::byte or unsigned char, then its okay to store an @@ -6704,6 +6731,15 @@ class BufferToAPValueConverter { if (T->isIntegralOrEnumerationType()) { Val.setIsSigned(T->isSignedIntegerOrEnumerationType()); + + unsigned IntWidth = Info.Ctx.getIntWidth(QualType(T, 0)); + if (IntWidth != Val.getBitWidth()) { + APSInt Truncated = Val.trunc(IntWidth); + if (Truncated.extend(Val.getBitWidth()) != Val) + return unrepresentableValue(QualType(T, 0), Val); + Val = Truncated; + } + return APValue(Val); } diff --git a/clang/lib/AST/IgnoreExpr.cpp b/clang/lib/AST/IgnoreExpr.cpp new file mode 100644 index 0000000000000..65aaaeb6a1ed0 --- /dev/null +++ b/clang/lib/AST/IgnoreExpr.cpp @@ -0,0 +1,129 @@ +//===--- IgnoreExpr.cpp - Ignore intermediate Expressions -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements common functions to ignore intermediate expression nodes +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/IgnoreExpr.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" + +using namespace clang; + +Expr *clang::IgnoreImplicitCastsSingleStep(Expr *E) { + if (auto *ICE = dyn_cast(E)) + return ICE->getSubExpr(); + + if (auto *FE = dyn_cast(E)) + return FE->getSubExpr(); + + return E; +} + +Expr *clang::IgnoreImplicitCastsExtraSingleStep(Expr *E) { + // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in + // addition to what IgnoreImpCasts() skips to account for the current + // behaviour of IgnoreParenImpCasts(). + Expr *SubE = IgnoreImplicitCastsSingleStep(E); + if (SubE != E) + return SubE; + + if (auto *MTE = dyn_cast(E)) + return MTE->getSubExpr(); + + if (auto *NTTP = dyn_cast(E)) + return NTTP->getReplacement(); + + return E; +} + +Expr *clang::IgnoreCastsSingleStep(Expr *E) { + if (auto *CE = dyn_cast(E)) + return CE->getSubExpr(); + + if (auto *FE = dyn_cast(E)) + return FE->getSubExpr(); + + if (auto *MTE = dyn_cast(E)) + return MTE->getSubExpr(); + + if (auto *NTTP = dyn_cast(E)) + return NTTP->getReplacement(); + + return E; +} + +Expr *clang::IgnoreLValueCastsSingleStep(Expr *E) { + // Skip what IgnoreCastsSingleStep skips, except that only + // lvalue-to-rvalue casts are skipped. + if (auto *CE = dyn_cast(E)) + if (CE->getCastKind() != CK_LValueToRValue) + return E; + + return IgnoreCastsSingleStep(E); +} + +Expr *clang::IgnoreBaseCastsSingleStep(Expr *E) { + if (auto *CE = dyn_cast(E)) + if (CE->getCastKind() == CK_DerivedToBase || + CE->getCastKind() == CK_UncheckedDerivedToBase || + CE->getCastKind() == CK_NoOp) + return CE->getSubExpr(); + + return E; +} + +Expr *clang::IgnoreImplicitSingleStep(Expr *E) { + Expr *SubE = IgnoreImplicitCastsSingleStep(E); + if (SubE != E) + return SubE; + + if (auto *MTE = dyn_cast(E)) + return MTE->getSubExpr(); + + if (auto *BTE = dyn_cast(E)) + return BTE->getSubExpr(); + + return E; +} + +Expr *clang::IgnoreImplicitAsWrittenSingleStep(Expr *E) { + if (auto *ICE = dyn_cast(E)) + return ICE->getSubExprAsWritten(); + + return IgnoreImplicitSingleStep(E); +} + +Expr *clang::IgnoreParensOnlySingleStep(Expr *E) { + if (auto *PE = dyn_cast(E)) + return PE->getSubExpr(); + return E; +} + +Expr *clang::IgnoreParensSingleStep(Expr *E) { + if (auto *PE = dyn_cast(E)) + return PE->getSubExpr(); + + if (auto *UO = dyn_cast(E)) { + if (UO->getOpcode() == UO_Extension) + return UO->getSubExpr(); + } + + else if (auto *GSE = dyn_cast(E)) { + if (!GSE->isResultDependent()) + return GSE->getResultExpr(); + } + + else if (auto *CE = dyn_cast(E)) { + if (!CE->isConditionDependent()) + return CE->getChosenSubExpr(); + } + + return E; +} diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 64e0da9e64b12..5b97265a6d8ae 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1266,13 +1266,21 @@ ClassifyDiagnostic(const AttrTy *A) { } bool ThreadSafetyAnalyzer::inCurrentScope(const CapabilityExpr &CapE) { - if (!CurrentMethod) + const threadSafety::til::SExpr *SExp = CapE.sexpr(); + assert(SExp && "Null expressions should be ignored"); + + // Global variables are always in scope. + if (isa(SExp)) + return true; + + // Members are in scope from methods of the same class. + if (const auto *P = dyn_cast(SExp)) { + if (!CurrentMethod) return false; - if (const auto *P = dyn_cast_or_null(CapE.sexpr())) { - const auto *VD = P->clangDecl(); - if (VD) - return VD->getDeclContext() == CurrentMethod->getDeclContext(); + const ValueDecl *VD = P->clangDecl(); + return VD->getDeclContext() == CurrentMethod->getDeclContext(); } + return false; } diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index 1b8c55e56d470..aee9185760071 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -274,7 +274,7 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE, const auto *VD = cast(DRE->getDecl()->getCanonicalDecl()); // Function parameters require substitution and/or renaming. - if (const auto *PV = dyn_cast_or_null(VD)) { + if (const auto *PV = dyn_cast(VD)) { unsigned I = PV->getFunctionScopeIndex(); const DeclContext *D = PV->getDeclContext(); if (Ctx && Ctx->FunArgs) { diff --git a/clang/lib/Basic/CodeGenOptions.cpp b/clang/lib/Basic/CodeGenOptions.cpp index 9e04b5ced2bb3..4fc7a535c9eb9 100644 --- a/clang/lib/Basic/CodeGenOptions.cpp +++ b/clang/lib/Basic/CodeGenOptions.cpp @@ -10,9 +10,8 @@ #include namespace clang { -CodeGenOptions::CodeGenOptions() - : FPDenormalMode(llvm::DenormalMode::getIEEE()), - FP32DenormalMode(llvm::DenormalMode::getIEEE()), Argv0(nullptr) { + +CodeGenOptions::CodeGenOptions() { #define CODEGENOPT(Name, Bits, Default) Name = Default; #define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default); #include "clang/Basic/CodeGenOptions.def" diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp index 344d326a92e48..c08670c87fb69 100644 --- a/clang/lib/Basic/LangOptions.cpp +++ b/clang/lib/Basic/LangOptions.cpp @@ -14,8 +14,7 @@ using namespace clang; -LangOptions::LangOptions() - : CFRuntime(CoreFoundationABI::Unspecified), IsHeaderFile(false) { +LangOptions::LangOptions() { #define LANGOPT(Name, Bits, Default, Description) Name = Default; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default); #include "clang/Basic/LangOptions.def" diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 6fd97d4e57869..7f0a0f0d86dc1 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -378,8 +378,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); if (Opts.ArmSveVectorBits) - Builder.defineMacro("__ARM_FEATURE_SVE_BITS_EXPERIMENTAL", - Twine(Opts.ArmSveVectorBits)); + Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.ArmSveVectorBits)); } ArrayRef AArch64TargetInfo::getTargetBuiltins() const { diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ddeec25d8cf5a..ff9dcd5022029 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -11320,16 +11320,6 @@ static Value *EmitX86ConvertIntToFp(CodeGenFunction &CGF, return EmitX86Select(CGF, Ops[2], Res, Ops[1]); } -static Value *EmitX86Abs(CodeGenFunction &CGF, ArrayRef Ops) { - - llvm::Type *Ty = Ops[0]->getType(); - Value *Zero = llvm::Constant::getNullValue(Ty); - Value *Sub = CGF.Builder.CreateSub(Zero, Ops[0]); - Value *Cmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Zero); - Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Sub); - return Res; -} - static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred, ArrayRef Ops) { Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); @@ -11549,13 +11539,9 @@ static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } -// Emit addition or subtraction with signed/unsigned saturation. -static Value *EmitX86AddSubSatExpr(CodeGenFunction &CGF, - ArrayRef Ops, bool IsSigned, - bool IsAddition) { - Intrinsic::ID IID = - IsSigned ? (IsAddition ? Intrinsic::sadd_sat : Intrinsic::ssub_sat) - : (IsAddition ? Intrinsic::uadd_sat : Intrinsic::usub_sat); +// Emit binary intrinsic with the same type used in result/args. +static Value *EmitX86BinaryIntrinsic(CodeGenFunction &CGF, + ArrayRef Ops, Intrinsic::ID IID) { llvm::Function *F = CGF.CGM.getIntrinsic(IID, Ops[0]->getType()); return CGF.Builder.CreateCall(F, {Ops[0], Ops[1]}); } @@ -13310,9 +13296,10 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_pabsb512: case X86::BI__builtin_ia32_pabsw512: case X86::BI__builtin_ia32_pabsd512: - case X86::BI__builtin_ia32_pabsq512: - return EmitX86Abs(*this, Ops); - + case X86::BI__builtin_ia32_pabsq512: { + Function *F = CGM.getIntrinsic(Intrinsic::abs, Ops[0]->getType()); + return Builder.CreateCall(F, {Ops[0], Builder.getInt1(false)}); + } case X86::BI__builtin_ia32_pmaxsb128: case X86::BI__builtin_ia32_pmaxsw128: case X86::BI__builtin_ia32_pmaxsd128: @@ -14039,28 +14026,28 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_paddsw256: case X86::BI__builtin_ia32_paddsb128: case X86::BI__builtin_ia32_paddsw128: - return EmitX86AddSubSatExpr(*this, Ops, true, true); + return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::sadd_sat); case X86::BI__builtin_ia32_paddusb512: case X86::BI__builtin_ia32_paddusw512: case X86::BI__builtin_ia32_paddusb256: case X86::BI__builtin_ia32_paddusw256: case X86::BI__builtin_ia32_paddusb128: case X86::BI__builtin_ia32_paddusw128: - return EmitX86AddSubSatExpr(*this, Ops, false, true); + return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::uadd_sat); case X86::BI__builtin_ia32_psubsb512: case X86::BI__builtin_ia32_psubsw512: case X86::BI__builtin_ia32_psubsb256: case X86::BI__builtin_ia32_psubsw256: case X86::BI__builtin_ia32_psubsb128: case X86::BI__builtin_ia32_psubsw128: - return EmitX86AddSubSatExpr(*this, Ops, true, false); + return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::ssub_sat); case X86::BI__builtin_ia32_psubusb512: case X86::BI__builtin_ia32_psubusw512: case X86::BI__builtin_ia32_psubusb256: case X86::BI__builtin_ia32_psubusw256: case X86::BI__builtin_ia32_psubusb128: case X86::BI__builtin_ia32_psubusw128: - return EmitX86AddSubSatExpr(*this, Ops, false, false); + return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::usub_sat); } } diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 8c3ed69d79b73..93ef2e42a1410 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1038,6 +1038,10 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty, uint64_t Size = 0; uint32_t Align = 0; + const RecordDecl *D = RD->getDefinition(); + if (D && D->isCompleteDefinition()) + Size = CGM.getContext().getTypeSize(Ty); + llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl; // Add flag to nontrivial forward declarations. To be consistent with MSVC, diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index d0e0c7d6c0603..50b6079bd80bf 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -220,7 +220,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( DevirtualizedMethod = MD->getCorrespondingMethodInClass(BestDynamicDecl); assert(DevirtualizedMethod); const CXXRecordDecl *DevirtualizedClass = DevirtualizedMethod->getParent(); - const Expr *Inner = Base->ignoreParenBaseCasts(); + const Expr *Inner = Base->IgnoreParenBaseCasts(); if (DevirtualizedMethod->getReturnType().getCanonicalType() != MD->getReturnType().getCanonicalType()) // If the return types are not the same, this might be a case where more diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 5c9f60ae5f0df..cd42d8a64f9c5 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -611,7 +611,7 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, FD->getAttr()) { llvm::LLVMContext &Context = getLLVMContext(); Optional ArgVal = - A->getSubGroupSize()->getIntegerConstantExpr(FD->getASTContext()); + A->getValue()->getIntegerConstantExpr(FD->getASTContext()); assert(ArgVal.hasValue() && "Not an integer constant expression"); llvm::Metadata *AttrMDArgs[] = {llvm::ConstantAsMetadata::get( Builder.getInt32(ArgVal->getSExtValue()))}; @@ -629,8 +629,12 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, if (const SYCLIntelNumSimdWorkItemsAttr *A = FD->getAttr()) { - llvm::Metadata *AttrMDArgs[] = { - llvm::ConstantAsMetadata::get(Builder.getInt32(A->getNumber()))}; + llvm::LLVMContext &Context = getLLVMContext(); + Optional ArgVal = + A->getValue()->getIntegerConstantExpr(FD->getASTContext()); + assert(ArgVal.hasValue() && "Not an integer constant expression"); + llvm::Metadata *AttrMDArgs[] = {llvm::ConstantAsMetadata::get( + Builder.getInt32(ArgVal->getSExtValue()))}; Fn->setMetadata("num_simd_work_items", llvm::MDNode::get(Context, AttrMDArgs)); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 257343f678388..a8da0b910092b 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2048,7 +2048,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, } void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) { - assert(!GV->isDeclaration() && + assert((isa(GV) || !GV->isDeclaration()) && "Only globals with definition can force usage."); LLVMUsed.emplace_back(GV); } @@ -2264,6 +2264,31 @@ void CodeGenModule::EmitDeferred() { CurDeclsToEmit.swap(DeferredDeclsToEmit); for (GlobalDecl &D : CurDeclsToEmit) { + const ValueDecl *VD = cast(D.getDecl()); + // If emitting for SYCL device, emit the deferred alias + // as well as what it aliases. + if (LangOpts.SYCLIsDevice) { + if (AliasAttr *Attr = VD->getAttr()) { + StringRef AliaseeName = Attr->getAliasee(); + auto DDI = DeferredDecls.find(AliaseeName); + // Emit what is aliased first. + if (DDI != DeferredDecls.end()) { + GlobalDecl GD = DDI->second; + llvm::GlobalValue *AliaseeGV = + dyn_cast(GetAddrOfGlobal(GD, ForDefinition)); + if (!AliaseeGV) + AliaseeGV = GetGlobalValue(getMangledName(GD)); + assert(AliaseeGV); + EmitGlobalDefinition(GD, AliaseeGV); + // Remove the entry just added to the DeferredDeclsToEmit + // since we have emitted it. + DeferredDeclsToEmit.pop_back(); + } + // Now emit the alias itself. + EmitAliasDefinition(D); + continue; + } + } // We should call GetAddrOfGlobal with IsForDefinition set to true in order // to get GlobalValue with exactly the type we need, not something that // might had been created for another decl with the same mangled name but @@ -2296,6 +2321,20 @@ void CodeGenModule::EmitDeferred() { // Otherwise, emit the definition and move on to the next one. EmitGlobalDefinition(D, GV); + if (LangOpts.SYCLIsDevice) { + // If there are any aliases deferred for this, emit those now. + for (auto It = DeferredAliases.begin(); It != DeferredAliases.end(); + /*no increment*/) { + const ValueDecl *Global = cast(It->second.getDecl()); + if (It->first == getMangledName(D)) { + EmitAliasDefinition(Global); + It = DeferredAliases.erase(It); + } else { + ++It; + } + } + } + // If we found out that we need to emit more decls, do that recursively. // This has the advantage that the decls are emitted in a DFS and related // ones are close together, which is convenient for testing. @@ -2619,9 +2658,19 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { return; // If this is an alias definition (which otherwise looks like a declaration) - // emit it now. - if (Global->hasAttr()) - return EmitAliasDefinition(GD); + // handle it now. + if (AliasAttr *Attr = Global->getAttr()) { + // Emit the alias here if it is not SYCL device compilation. + if (!LangOpts.SYCLIsDevice) + return EmitAliasDefinition(GD); + // Defer for SYCL devices, until either the alias or what it aliases + // is used. + StringRef MangledName = getMangledName(GD); + DeferredDecls[MangledName] = GD; + StringRef AliaseeName = Attr->getAliasee(); + DeferredAliases[AliaseeName] = GD; + return; + } // IFunc like an alias whose value is resolved at runtime by calling resolver. if (Global->hasAttr()) @@ -4836,20 +4885,21 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { // if a deferred decl. llvm::Constant *Aliasee; llvm::GlobalValue::LinkageTypes LT; + unsigned AS; if (isa(DeclTy)) { Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GD, /*ForVTable=*/false); LT = getFunctionLinkage(GD); + AS = Aliasee->getType()->getPointerAddressSpace(); } else { - Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), - llvm::PointerType::getUnqual(DeclTy), + AS = ArgInfoAddressSpace(GetGlobalVarAddressSpace(/*D=*/nullptr)); + Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), DeclTy->getPointerTo(AS), /*D=*/nullptr); LT = getLLVMLinkageVarDefinition(cast(GD.getDecl()), D->getType().isConstQualified()); } // Create the new alias itself, but don't set a name yet. - unsigned AS = Aliasee->getType()->getPointerAddressSpace(); auto *GA = llvm::GlobalAlias::create(DeclTy, AS, LT, "", Aliasee, &getModule()); @@ -4870,8 +4920,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { // Remove it and replace uses of it with the alias. GA->takeName(Entry); - Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA, - Entry->getType())); + Entry->replaceAllUsesWith( + llvm::ConstantExpr::getBitCast(GA, Entry->getType())); Entry->eraseFromParent(); } else { GA->setName(MangledName); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 2037571f38829..cac10a97e7106 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -345,6 +345,11 @@ class CodeGenModule : public CodeGenTypeCache { /// yet. std::map DeferredDecls; + /// This contains all the aliases that are deferred for emission until + /// they or what they alias are actually used. Note that the StringRef + /// associated in this map is that of the aliasee. + std::map DeferredAliases; + /// This is a list of deferred decls which we have seen that *are* actually /// referenced. These get code generated when the module is done. std::vector DeferredDeclsToEmit; diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 50a0523a495a4..3ca5ca2ffb4c6 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -9066,13 +9066,9 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes( assert(Max == 0 && "Max must be zero"); } else if (IsOpenCLKernel || IsHIPKernel) { // By default, restrict the maximum size to a value specified by - // --gpu-max-threads-per-block=n or its default value for HIP. - const unsigned OpenCLDefaultMaxWorkGroupSize = 256; - const unsigned DefaultMaxWorkGroupSize = - IsOpenCLKernel ? OpenCLDefaultMaxWorkGroupSize - : M.getLangOpts().GPUMaxThreadsPerBlock; + // --gpu-max-threads-per-block=n or its default value. std::string AttrVal = - std::string("1,") + llvm::utostr(DefaultMaxWorkGroupSize); + std::string("1,") + llvm::utostr(M.getLangOpts().GPUMaxThreadsPerBlock); F->addFnAttr("amdgpu-flat-work-group-size", AttrVal); } diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp index c24a6f3765f26..46a82dce89c8a 100644 --- a/clang/lib/Driver/Compilation.cpp +++ b/clang/lib/Driver/Compilation.cpp @@ -150,7 +150,8 @@ bool Compilation::CleanupFileList(const TempFileList &Files, // Temporary file lists contain files that need to be cleaned. The // file containing the information is also removed if (File.second == types::TY_Tempfilelist || - File.second == types::TY_Tempfiletable) { + File.second == types::TY_Tempfiletable || + File.second == types::TY_FPGA_Dependencies_List) { // These are temporary files and need to be removed. bool IsTable = File.second == types::TY_Tempfiletable; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 5681a8beb363a..57a14c56190b1 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5,7 +5,6 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - #include "clang/Driver/Driver.h" #include "InputInfo.h" #include "ToolChains/AIX.h" @@ -811,14 +810,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, return SYCLArg; }; - // Emit an error if c-compilation is forced in -fsycl mode - if (HasValidSYCLRuntime) - for (StringRef XValue : C.getInputArgs().getAllArgValues(options::OPT_x)) { - if (XValue == "c" || XValue == "c-header") - C.getDriver().Diag(clang::diag::err_drv_fsycl_with_c_type) - << "-x " << XValue; - } - Arg *SYCLTargets = getArgRequiringSYCLRuntime(options::OPT_fsycl_targets_EQ); Arg *SYCLLinkTargets = getArgRequiringSYCLRuntime(options::OPT_fsycl_link_targets_EQ); @@ -1788,20 +1779,21 @@ llvm::Triple Driver::MakeSYCLDeviceTriple(StringRef TargetArch) const { // Print the help from any of the given tools which are used for AOT // compilation for SYCL void Driver::PrintSYCLToolHelp(const Compilation &C) const { - SmallVector, 4> HelpArgs; + SmallVector, 4> + HelpArgs; // Populate the vector with the tools and help options if (Arg *A = C.getArgs().getLastArg(options::OPT_fsycl_help_EQ)) { StringRef AV(A->getValue()); llvm::Triple T; if (AV == "gen" || AV == "all") HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_gen"), - "ocloc", "--help")); + "ocloc", "--help", "")); if (AV == "fpga" || AV == "all") - HelpArgs.push_back( - std::make_tuple(MakeSYCLDeviceTriple("spir64_fpga"), "aoc", "-help")); + HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_fpga"), + "aoc", "-help", "-sycl")); if (AV == "x86_64" || AV == "all") HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_x86_64"), - "opencl-aot", "--help")); + "opencl-aot", "--help", "")); if (HelpArgs.empty()) { C.getDriver().Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << AV; @@ -1814,7 +1806,8 @@ void Driver::PrintSYCLToolHelp(const Compilation &C) const { llvm::outs() << "Emitting help information for " << std::get<1>(HA) << '\n' << "Use triple of '" << std::get<0>(HA).normalize() << "' to enable ahead of time compilation\n"; - std::vector ToolArgs = { std::get<1>(HA), std::get<2>(HA) }; + std::vector ToolArgs = {std::get<1>(HA), std::get<2>(HA), + std::get<3>(HA)}; SmallString<128> ExecPath( C.getDefaultToolChain().GetProgramPath(std::get<1>(HA).data())); auto ToolBinary = llvm::sys::findProgramByName(ExecPath); @@ -1824,7 +1817,10 @@ void Driver::PrintSYCLToolHelp(const Compilation &C) const { } // do not run the tools with -###. if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) { - llvm::errs() << "\"" << ExecPath << "\" \"" << ToolArgs[1] << "\"\n"; + llvm::errs() << "\"" << ExecPath << "\" \"" << ToolArgs[1] << "\""; + if (!ToolArgs[2].empty()) + llvm::errs() << " \"" << ToolArgs[2] << "\""; + llvm::errs() << "\n"; continue; } // Run the Tool. @@ -2381,12 +2377,13 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // actually use it, so we warn about unused -x arguments. types::ID InputType = types::TY_Nothing; Arg *InputTypeArg = nullptr; + bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false); // The last /TC or /TP option sets the input type to C or C++ globally. if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) { InputTypeArg = TCTP; - InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) + InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) && !IsSYCL ? types::TY_C : types::TY_CXX; @@ -2419,6 +2416,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (InputTypeArg) InputTypeArg->claim(); + types::ID CType = types::TY_C; + // For SYCL, all source file inputs are considered C++. + if (IsSYCL) + CType = types::TY_CXX; + // stdin must be handled specially. if (memcmp(Value, "-", 2) == 0) { // If running with -E, treat as a C input (this changes the builtin @@ -2429,7 +2431,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP()) Diag(IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl : clang::diag::err_drv_unknown_stdin_type); - Ty = types::TY_C; + Ty = CType; } else { // Otherwise lookup by extension. // Fallback is C if invoked as C preprocessor, C++ if invoked with @@ -2439,9 +2441,29 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (const char *Ext = strrchr(Value, '.')) Ty = TC.LookupTypeForExtension(Ext + 1); + // For SYCL, convert C-type sources to C++-type sources. + if (IsSYCL) { + switch (Ty) { + case types::TY_C: + Ty = types::TY_CXX; + break; + case types::TY_CHeader: + Ty = types::TY_CXXHeader; + break; + case types::TY_PP_C: + Ty = types::TY_PP_CXX; + break; + case types::TY_PP_CHeader: + Ty = types::TY_PP_CXXHeader; + break; + default: + break; + } + } + if (Ty == types::TY_INVALID) { if (CCCIsCPP()) - Ty = types::TY_C; + Ty = CType; else if (IsCLMode() && Args.hasArgNoClaim(options::OPT_E)) Ty = types::TY_CXX; else @@ -2500,7 +2522,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (DiagnoseInputExistence(Args, Value, types::TY_C, /*TypoCorrect=*/false)) { Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); - Inputs.push_back(std::make_pair(types::TY_C, InputArg)); + Inputs.push_back( + std::make_pair(IsSYCL ? types::TY_CXX : types::TY_C, InputArg)); } A->claim(); } else if (A->getOption().matches(options::OPT__SLASH_Tp)) { @@ -2528,6 +2551,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, Diag(clang::diag::err_drv_unknown_language) << A->getValue(); InputType = types::TY_Object; } + // Emit an error if c-compilation is forced in -fsycl mode + if (IsSYCL && (InputType == types::TY_C || InputType == types::TY_PP_C || + InputType == types::TY_CHeader)) + Diag(clang::diag::err_drv_fsycl_with_c_type) << A->getAsString(Args); + } else if (A->getOption().getID() == options::OPT_U) { assert(A->getNumValues() == 1 && "The /U option has one value."); StringRef Val = A->getValue(0); @@ -2715,6 +2743,16 @@ static SmallVector getLinkerArgs(Compilation &C, return LibArgs; } +static bool IsSYCLDeviceLibObj(std::string ObjFilePath, bool isMSVCEnv) { + StringRef ObjFileName = llvm::sys::path::filename(ObjFilePath); + StringRef ObjSuffix = isMSVCEnv ? ".obj" : ".o"; + bool Ret = + (ObjFileName.startswith("libsycl-") && ObjFileName.endswith(ObjSuffix)) + ? true + : false; + return Ret; +} + // Goes through all of the arguments, including inputs expected for the // linker directly, to determine if we need to perform additional work for // static offload libraries. @@ -3613,6 +3651,9 @@ class OffloadingActionBuilder final { /// List of objects to extract FPGA dependency info from ActionList FPGAObjectInputs; + /// List of static archives to extract FPGA dependency info from + ActionList FPGAArchiveInputs; + /// List of CUDA architectures to use in this compilation with NVPTX targets. SmallVector GpuArchList; @@ -3790,7 +3831,13 @@ class OffloadingActionBuilder final { if (IA->getType() == types::TY_Object) { if (!isObjectFile(FileName)) return ABRT_Inactive; - if (Args.hasArg(options::OPT_fintelfpga)) + // For SYCL device libraries, don't need to add them to + // FPGAObjectInputs as there is no FPGA dep files inside. + + if (Args.hasArg(options::OPT_fintelfpga) && + !IsSYCLDeviceLibObj(FileName, C.getDefaultToolChain() + .getTriple() + .isWindowsMSVCEnvironment())) FPGAObjectInputs.push_back(IA); } // When creating FPGA device fat objects, all host objects are @@ -3854,6 +3901,92 @@ class OffloadingActionBuilder final { SYCLDeviceActions.clear(); } + void addSYCLDeviceLibs(const ToolChain *TC, ActionList &DeviceLinkObjects, + bool isSpirvAOT, bool isMSVCEnv) { + enum SYCLDeviceLibType { + sycl_devicelib_wrapper, + sycl_devicelib_fallback + }; + struct DeviceLibOptInfo { + StringRef devicelib_name; + StringRef devicelib_option; + }; + + bool NoDeviceLibs = false; + // Currently, libc, libm-fp32 will be linked in by default. In order + // to use libm-fp64, -fsycl-device-lib=libm-fp64/all should be used. + llvm::StringMap devicelib_link_info = { + {"libc", true}, {"libm-fp32", true}, {"libm-fp64", false}}; + if (Arg *A = Args.getLastArg(options::OPT_fsycl_device_lib_EQ, + options::OPT_fno_sycl_device_lib_EQ)) { + if (A->getValues().size() == 0) + C.getDriver().Diag(diag::warn_drv_empty_joined_argument) + << A->getAsString(Args); + else { + if (A->getOption().matches(options::OPT_fno_sycl_device_lib_EQ)) + NoDeviceLibs = true; + + for (StringRef Val : A->getValues()) { + if (Val == "all") { + for (auto &K : devicelib_link_info.keys()) + devicelib_link_info[K] = true && !NoDeviceLibs; + break; + } + auto LinkInfoIter = devicelib_link_info.find(Val); + if (LinkInfoIter == devicelib_link_info.end()) { + C.getDriver().Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Val; + } + devicelib_link_info[Val] = true && !NoDeviceLibs; + } + } + } + + SmallString<128> LibLoc(TC->getDriver().Dir); + llvm::sys::path::append(LibLoc, "/../lib"); + StringRef LibSuffix = isMSVCEnv ? ".obj" : ".o"; + SmallVector sycl_device_wrapper_libs = { + {"libsycl-crt", "libc"}, + {"libsycl-complex", "libm-fp32"}, + {"libsycl-complex-fp64", "libm-fp64"}, + {"libsycl-cmath", "libm-fp32"}, + {"libsycl-cmath-fp64", "libm-fp64"}}; + // For AOT compilation, we need to link sycl_device_fallback_libs as + // default too. + SmallVector sycl_device_fallback_libs = { + {"libsycl-fallback-cassert", "libc"}, + {"libsycl-fallback-complex", "libm-fp32"}, + {"libsycl-fallback-complex-fp64", "libm-fp64"}, + {"libsycl-fallback-cmath", "libm-fp32"}, + {"libsycl-fallback-cmath-fp64", "libm-fp64"}}; + auto addInputs = [&](SYCLDeviceLibType t) { + auto sycl_libs = (t == sycl_devicelib_wrapper) + ? sycl_device_wrapper_libs + : sycl_device_fallback_libs; + for (const DeviceLibOptInfo &Lib : sycl_libs) { + if (!devicelib_link_info[Lib.devicelib_option]) + continue; + SmallString<128> LibName(LibLoc); + llvm::sys::path::append(LibName, Lib.devicelib_name); + llvm::sys::path::replace_extension(LibName, LibSuffix); + if (llvm::sys::fs::exists(LibName)) { + Arg *InputArg = MakeInputArg(Args, C.getDriver().getOpts(), + Args.MakeArgString(LibName)); + auto *SYCLDeviceLibsInputAction = + C.MakeAction(*InputArg, types::TY_Object); + auto *SYCLDeviceLibsUnbundleAction = + C.MakeAction( + SYCLDeviceLibsInputAction); + addDeviceDepences(SYCLDeviceLibsUnbundleAction); + DeviceLinkObjects.push_back(SYCLDeviceLibsUnbundleAction); + } + } + }; + addInputs(sycl_devicelib_wrapper); + if (isSpirvAOT) + addInputs(sycl_devicelib_fallback); + } + void appendLinkDependences(OffloadAction::DeviceDependences &DA) override { assert(ToolChains.size() == DeviceLinkerInputs.size() && "Toolchains and linker inputs sizes do not match."); @@ -3933,6 +4066,11 @@ class OffloadingActionBuilder final { } ActionList DeviceLibObjects; ActionList LinkObjects; + auto TT = SYCLTripleList[I]; + auto isNVPTX = (*TC)->getTriple().isNVPTX(); + bool isSpirvAOT = TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga || + TT.getSubArch() == llvm::Triple::SPIRSubArch_gen || + TT.getSubArch() == llvm::Triple::SPIRSubArch_x86_64; for (const auto &Input : LI) { // FPGA aoco does not go through the link, everything else does. if (Input->getType() == types::TY_FPGA_AOCO) @@ -3940,6 +4078,15 @@ class OffloadingActionBuilder final { else LinkObjects.push_back(Input); } + // FIXME: Link all wrapper and fallback device libraries as default, + // When spv online link is supported by all backends, the fallback + // device libraries are only needed when current toolchain is using + // AOT compilation. + if (!isNVPTX) { + addSYCLDeviceLibs( + *TC, LinkObjects, true, + C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()); + } // The linkage actions subgraph leading to the offload wrapper. // [cond] Means incoming/outgoing dependence is created only when cond // is true. A function of: @@ -3994,7 +4141,6 @@ class OffloadingActionBuilder final { Action *DeviceLinkAction = C.MakeAction(LinkObjects, types::TY_LLVM_BC); // setup some flags upfront - auto isNVPTX = (*TC)->getTriple().isNVPTX(); if (isNVPTX && DeviceCodeSplit) { // TODO Temporary limitation, need to support code splitting for PTX @@ -4006,10 +4152,6 @@ class OffloadingActionBuilder final { D.Diag(diag::err_drv_unsupported_opt_for_target) << OptName << (*TC)->getTriple().str(); } - auto TT = SYCLTripleList[I]; - bool isSpirvAOT = TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga || - TT.getSubArch() == llvm::Triple::SPIRSubArch_gen || - TT.getSubArch() == llvm::Triple::SPIRSubArch_x86_64; // reflects whether current target is ahead-of-time and can't support // runtime setting of specialization constants bool isAOT = isNVPTX || isSpirvAOT; @@ -4061,15 +4203,19 @@ class OffloadingActionBuilder final { // triple calls for it (provided a valid subarch). ActionList BEInputs; BEInputs.push_back(BuildCodeAction); - for (Action *A : FPGAObjectInputs) { - // Send any known objects through the unbundler to grab the - // dependency file associated. + auto unbundleAdd = [&](Action *A, types::ID T) { ActionList AL; AL.push_back(A); - Action *UnbundleAction = C.MakeAction( - AL, types::TY_FPGA_Dependencies); + Action *UnbundleAction = + C.MakeAction(AL, T); BEInputs.push_back(UnbundleAction); - } + }; + // Send any known objects/archives through the unbundler to grab the + // dependency file associated. + for (Action *A : FPGAObjectInputs) + unbundleAdd(A, types::TY_FPGA_Dependencies); + for (Action *A : FPGAArchiveInputs) + unbundleAdd(A, types::TY_FPGA_Dependencies_List); for (const auto &A : DeviceLibObjects) BEInputs.push_back(A); BuildCodeAction = @@ -4194,6 +4340,7 @@ class OffloadingActionBuilder final { Arg *SYCLAddTargets = Args.getLastArg(options::OPT_fsycl_add_targets_EQ); bool HasValidSYCLRuntime = C.getInputArgs().hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false); + bool SYCLfpgaTriple = false; if (SYCLTargets || SYCLAddTargets) { if (SYCLTargets) { llvm::StringMap FoundNormalizedTriples; @@ -4211,6 +4358,8 @@ class OffloadingActionBuilder final { FoundNormalizedTriples[NormalizedName] = Val; SYCLTripleList.push_back(TT); + if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga) + SYCLfpgaTriple = true; } } if (SYCLAddTargets) { @@ -4234,6 +4383,8 @@ class OffloadingActionBuilder final { const char *SYCLTargetArch = SYCLfpga ? "spir64_fpga" : "spir64"; SYCLTripleList.push_back( C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch)); + if (SYCLfpga) + SYCLfpgaTriple = true; } // Set the FPGA output type based on command line (-fsycl-link). @@ -4241,6 +4392,21 @@ class OffloadingActionBuilder final { FPGAOutType = (A->getValue() == StringRef("early")) ? types::TY_FPGA_AOCR : types::TY_FPGA_AOCX; + // Populate FPGA static archives that could contain dep files to be + // incorporated into the aoc compilation + if (SYCLfpgaTriple) { + SmallVector LinkArgs(getLinkerArgs(C, Args)); + for (const StringRef &LA : LinkArgs) { + if (isStaticArchiveFile(LA) && hasOffloadSections(C, LA, Args)) { + const llvm::opt::OptTable &Opts = C.getDriver().getOpts(); + Arg *InputArg = MakeInputArg(Args, Opts, Args.MakeArgString(LA)); + Action *Current = + C.MakeAction(*InputArg, types::TY_Archive); + FPGAArchiveInputs.push_back(Current); + } + } + } + DeviceLinkerInputs.resize(ToolChains.size()); return initializeGpuArchMap(); } @@ -4996,14 +5162,33 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, // For an FPGA archive, we add the unbundling step above to take care of // the device side, but also unbundle here to extract the host side - for (const auto &LI : LinkerInputs) { + bool EarlyLink = false; + if (const Arg *A = Args.getLastArg(options::OPT_fsycl_link_EQ)) + EarlyLink = A->getValue() == StringRef("early"); + for (auto &LI : LinkerInputs) { Action *UnbundlerInput = nullptr; + auto wrapObject = [&] { + if (EarlyLink && Args.hasArg(options::OPT_fintelfpga)) { + // Only wrap the object with -fsycl-link=early + auto *BC = C.MakeAction(LI, types::TY_LLVM_BC); + auto *ASM = C.MakeAction(BC, types::TY_PP_Asm); + LI = C.MakeAction(ASM, types::TY_Object); + } + }; if (auto *IA = dyn_cast(LI)) { if (IA->getType() == types::TY_FPGA_AOCR || IA->getType() == types::TY_FPGA_AOCX) { // Add to unbundler. UnbundlerInput = LI; + } else { + std::string FileName = IA->getInputArg().getAsString(Args); + if ((IA->getType() == types::TY_Object && !isObjectFile(FileName)) || + IA->getInputArg().getOption().hasFlag(options::LinkerInput)) + continue; + wrapObject(); } + } else { + wrapObject(); } if (UnbundlerInput && !PL.empty()) { if (auto *IA = dyn_cast(UnbundlerInput)) { @@ -5976,12 +6161,14 @@ InputInfo Driver::BuildJobsForActionNoCache( // Do a check for a dependency file unbundle for FPGA. This is out of line // from a regular unbundle, so just create and return the name of the // unbundled file. - if (JA->getType() == types::TY_FPGA_Dependencies) { + if (JA->getType() == types::TY_FPGA_Dependencies || + JA->getType() == types::TY_FPGA_Dependencies_List) { + std::string Ext(types::getTypeTempSuffix(JA->getType())); std::string TmpFileName = - C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), "d"); + C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), Ext); const char *TmpFile = C.addTempFile(C.getArgs().MakeArgString(TmpFileName)); - Result = InputInfo(types::TY_FPGA_Dependencies, TmpFile, TmpFile); + Result = InputInfo(JA->getType(), TmpFile, TmpFile); UnbundlingResults.push_back(Result); } else { // Now that we have all the results generated, select the one that should @@ -6015,8 +6202,6 @@ InputInfo Driver::BuildJobsForActionNoCache( OffloadingPrefix += "-wrapper"; if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) BaseInput = FinalOutput->getValue(); - else - BaseInput = getDefaultImageName(); } } Result = InputInfo(A, GetNamedOutputPath(C, *JA, BaseInput, BoundArch, diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index cce0eb557a9c6..0f51443010ca4 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -866,8 +866,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, LinkCXXRuntimes) || D.CCCIsCXX(); - NeedsHeapProfRt = - Args.hasFlag(options::OPT_fmemprof, options::OPT_fno_memprof, false); + NeedsHeapProfRt = Args.hasFlag(options::OPT_fmemory_profile, + options::OPT_fno_memory_profile, false); // Finally, initialize the set of available and recoverable sanitizers. Sanitizers.Mask |= Kinds; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index faf0b84963926..7b264290b3e7c 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1255,6 +1255,10 @@ llvm::opt::DerivedArgList *ToolChain::TranslateOffloadTargetArgs( continue; } } + + if (!XOffloadTargetArg) + continue; + XOffloadTargetArg->setBaseArg(A); A = XOffloadTargetArg.release(); AllocatedArgs.push_back(A); diff --git a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp index 043b7f257c01d..70ba8eb2a7d0d 100644 --- a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp @@ -21,12 +21,19 @@ using namespace llvm::opt; const char *sparc::getSparcAsmModeForCPU(StringRef Name, const llvm::Triple &Triple) { if (Triple.getArch() == llvm::Triple::sparcv9) { + const char *DefV9CPU; + + if (Triple.isOSLinux() || Triple.isOSFreeBSD() || Triple.isOSOpenBSD()) + DefV9CPU = "-Av9a"; + else + DefV9CPU = "-Av9"; + return llvm::StringSwitch(Name) .Case("niagara", "-Av9b") .Case("niagara2", "-Av9b") .Case("niagara3", "-Av9d") .Case("niagara4", "-Av9d") - .Default("-Av9"); + .Default(DefV9CPU); } else { return llvm::StringSwitch(Name) .Case("v8", "-Av8") diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0230fff80dea0..ca756ea3cc6a1 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -26,6 +26,7 @@ #include "clang/Basic/CharInfo.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/LangStandard.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/Version.h" #include "clang/Driver/Distro.h" @@ -4056,10 +4057,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // device toolchain. bool UseSYCLTriple = IsSYCLDevice && (!IsSYCL || IsSYCLOffloadDevice); - // Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in + // Adjust IsWindowsXYZ for CUDA/HIP/SYCL compilations. Even when compiling in // device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not // Windows), we need to pass Windows-specific flags to cc1. - if (IsCuda || IsHIP) + if (IsCuda || IsHIP || IsSYCL) IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment(); // C++ is not supported for IAMCU. @@ -4155,7 +4156,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fenable-sycl-dae"); // Pass the triple of host when doing SYCL - auto AuxT = llvm::Triple(llvm::sys::getProcessTriple()); + llvm::Triple AuxT = C.getDefaultToolChain().getTriple(); + if (Args.hasFlag(options::OPT_fsycl_device_only, OptSpecifier(), false)) + AuxT = llvm::Triple(llvm::sys::getProcessTriple()); std::string NormalizedTriple = AuxT.normalize(); CmdArgs.push_back("-aux-triple"); CmdArgs.push_back(Args.MakeArgString(NormalizedTriple)); @@ -4366,8 +4369,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.getLastArg(options::OPT_save_temps_EQ)) Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ); - if (Args.hasFlag(options::OPT_fmemprof, options::OPT_fno_memprof, false)) - Args.AddLastArg(CmdArgs, options::OPT_fmemprof); + if (Args.hasFlag(options::OPT_fmemory_profile, + options::OPT_fno_memory_profile, false)) + Args.AddLastArg(CmdArgs, options::OPT_fmemory_profile); // Embed-bitcode option. // Only white-listed flags below are allowed to be embedded. @@ -5150,8 +5154,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-std=c++98"); else CmdArgs.push_back("-std=c89"); - else + else { + if (Args.hasArg(options::OPT_fsycl)) { + // Use of -std= with 'C' is not supported for SYCL. + const LangStandard *LangStd = + LangStandard::getLangStandardForName(Std->getValue()); + if (LangStd && LangStd->getLanguage() == Language::C) + D.Diag(diag::err_drv_argument_not_allowed_with) + << Std->getAsString(Args) << "-fsycl"; + } Std->render(Args, CmdArgs); + } // If -f(no-)trigraphs appears after the language standard flag, honor it. if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi, @@ -5171,7 +5184,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, /*Joined=*/true); else if (IsWindowsMSVC) ImplyVCPPCXXVer = true; - else if (IsSYCL) + + if (IsSYCL && types::isCXX(InputType) && + !Args.hasArg(options::OPT__SLASH_std)) // For DPC++, we default to -std=c++17 for all compilations. Use of -std // on the command line will override. CmdArgs.push_back("-std=c++17"); @@ -5357,6 +5372,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var, + options::OPT_fno_visibility_inlines_hidden_static_local_var); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden); Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ); @@ -5753,12 +5770,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } if (LanguageStandard.empty()) { - if (IsMSVC2015Compatible) - if (IsSYCL) - // For DPC++, C++17 is the default. - LanguageStandard = "-std=c++17"; - else - LanguageStandard = "-std=c++14"; + if (IsSYCL) + // For DPC++, C++17 is the default. + LanguageStandard = "-std=c++17"; + else if (IsMSVC2015Compatible) + LanguageStandard = "-std=c++14"; else LanguageStandard = "-std=c++11"; } @@ -6252,6 +6268,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasFlag(options::OPT_fsycl_esimd, options::OPT_fno_sycl_esimd, false)) CmdArgs.push_back("-fsycl-explicit-simd"); + + if (!D.IsCLMode()) { + // SYCL library is guaranteed to work correctly only with dynamic + // MSVC runtime. + llvm::Triple AuxT = C.getDefaultToolChain().getTriple(); + if (Args.hasFlag(options::OPT_fsycl_device_only, OptSpecifier(), false)) + AuxT = llvm::Triple(llvm::sys::getProcessTriple()); + if (AuxT.isWindowsMSVCEnvironment()) { + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("-D_DLL"); + CmdArgs.push_back("--dependent-lib=msvcrt"); + } + } } if (IsSYCLOffloadDevice && JA.getType() == types::TY_SYCL_Header) { // Generating a SYCL Header @@ -6764,40 +6793,56 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, bool *EmitCodeView) const { unsigned RTOptionID = options::OPT__SLASH_MT; bool isNVPTX = getToolChain().getTriple().isNVPTX(); + bool isSYCLDevice = + getToolChain().getTriple().getEnvironment() == llvm::Triple::SYCLDevice; + bool isSYCL = Args.hasArg(options::OPT_fsycl) || isSYCLDevice; + // For SYCL Windows, /MD is the default. + if (isSYCL) + RTOptionID = options::OPT__SLASH_MD; if (Args.hasArg(options::OPT__SLASH_LDd)) - // The /LDd option implies /MTd. The dependent lib part can be overridden, - // but defining _DEBUG is sticky. - RTOptionID = options::OPT__SLASH_MTd; + // The /LDd option implies /MTd (/MDd for SYCL). The dependent lib part + // can be overridden but defining _DEBUG is sticky. + RTOptionID = isSYCL ? options::OPT__SLASH_MDd : options::OPT__SLASH_MTd; - if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) + if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) { RTOptionID = A->getOption().getID(); + if (isSYCL && !isSYCLDevice && + (RTOptionID == options::OPT__SLASH_MT || + RTOptionID == options::OPT__SLASH_MTd)) + // Use of /MT or /MTd is not supported for SYCL. + getToolChain().getDriver().Diag(diag::err_drv_unsupported_opt_dpcpp) + << A->getOption().getName(); + } + enum { addDEBUG = 0x1, addMT = 0x2, addDLL = 0x4 }; + auto addPreDefines = [&](unsigned Defines) { + if (Defines & addDEBUG) + CmdArgs.push_back("-D_DEBUG"); + if (Defines & addMT && !isSYCLDevice) + CmdArgs.push_back("-D_MT"); + if (Defines & addDLL && !isSYCLDevice) + CmdArgs.push_back("-D_DLL"); + }; StringRef FlagForCRT; switch (RTOptionID) { case options::OPT__SLASH_MD: - if (Args.hasArg(options::OPT__SLASH_LDd)) - CmdArgs.push_back("-D_DEBUG"); - CmdArgs.push_back("-D_MT"); - CmdArgs.push_back("-D_DLL"); + addPreDefines((Args.hasArg(options::OPT__SLASH_LDd) ? addDEBUG : 0x0) | + addMT | addDLL); FlagForCRT = "--dependent-lib=msvcrt"; break; case options::OPT__SLASH_MDd: - CmdArgs.push_back("-D_DEBUG"); - CmdArgs.push_back("-D_MT"); - CmdArgs.push_back("-D_DLL"); + addPreDefines(addDEBUG | addMT | addDLL); FlagForCRT = "--dependent-lib=msvcrtd"; break; case options::OPT__SLASH_MT: - if (Args.hasArg(options::OPT__SLASH_LDd)) - CmdArgs.push_back("-D_DEBUG"); - CmdArgs.push_back("-D_MT"); + addPreDefines((Args.hasArg(options::OPT__SLASH_LDd) ? addDEBUG : 0x0) | + addMT); CmdArgs.push_back("-flto-visibility-public-std"); FlagForCRT = "--dependent-lib=libcmt"; break; case options::OPT__SLASH_MTd: - CmdArgs.push_back("-D_DEBUG"); - CmdArgs.push_back("-D_MT"); + addPreDefines(addDEBUG | addMT); CmdArgs.push_back("-flto-visibility-public-std"); FlagForCRT = "--dependent-lib=libcmtd"; break; @@ -6814,6 +6859,15 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, // users want. The /Za flag to cl.exe turns this off, but it's not // implemented in clang. CmdArgs.push_back("--dependent-lib=oldnames"); + + // Add SYCL dependent library + if (Args.hasArg(options::OPT_fsycl) && + !Args.hasArg(options::OPT_nolibsycl)) { + if (RTOptionID == options::OPT__SLASH_MDd) + CmdArgs.push_back("--dependent-lib=sycld"); + else + CmdArgs.push_back("--dependent-lib=sycl"); + } } if (Arg *ShowIncludes = @@ -7399,7 +7453,8 @@ void OffloadBundler::ConstructJobMultipleOutputs( bool IsMSVCEnv = C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment(); types::ID InputType(Input.getType()); - bool IsFPGADepUnbundle = (JA.getType() == types::TY_FPGA_Dependencies); + bool IsFPGADepUnbundle = JA.getType() == types::TY_FPGA_Dependencies; + bool IsFPGADepLibUnbundle = JA.getType() == types::TY_FPGA_Dependencies_List; bool IsArchiveUnbundle = (!IsMSVCEnv && C.getDriver().getOffloadStaticLibSeen() && (types::isArchive(InputType) || InputType == types::TY_Object)); @@ -7415,7 +7470,7 @@ void OffloadBundler::ConstructJobMultipleOutputs( else TypeArg = "aoo"; } - if (InputType == types::TY_FPGA_AOCO || + if (InputType == types::TY_FPGA_AOCO || IsFPGADepLibUnbundle || (IsMSVCEnv && types::isArchive(InputType))) TypeArg = "aoo"; if (IsFPGADepUnbundle) @@ -7474,7 +7529,7 @@ void OffloadBundler::ConstructJobMultipleOutputs( Triples += Dep.DependentBoundArch; } } - if (IsFPGADepUnbundle) { + if (IsFPGADepUnbundle || IsFPGADepLibUnbundle) { // TODO - We are currently using the target triple inputs to slot a location // of the dependency information into the bundle. It would be good to // separate this out to an explicit option in the bundler for the dependency @@ -7495,7 +7550,7 @@ void OffloadBundler::ConstructJobMultipleOutputs( // When dealing with -fintelfpga, there is an additional unbundle step // that occurs for the dependency file. In that case, do not use the // dependent information, but just the output file. - if (IsFPGADepUnbundle) + if (IsFPGADepUnbundle || IsFPGADepLibUnbundle) UB += Outputs[0].getFilename(); else { for (unsigned I = 0; I < Outputs.size(); ++I) { @@ -7670,6 +7725,30 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA, assert(JA.getInputs().size() == Inputs.size() && "Not have inputs for all dependence actions??"); + // For FPGA, we wrap the host objects before archiving them when using + // -fsycl-link. This allows for better extraction control from the + // archive when we need the host objects for subsequent compilations. + if (OffloadingKind == Action::OFK_None && + C.getArgs().hasArg(options::OPT_fintelfpga) && + C.getArgs().hasArg(options::OPT_fsycl_link_EQ)) { + + // Add offload targets and inputs. + CmdArgs.push_back(C.getArgs().MakeArgString( + Twine("-kind=") + Action::GetOffloadKindName(OffloadingKind))); + CmdArgs.push_back( + TCArgs.MakeArgString(Twine("-target=") + Triple.getTriple())); + + // Add input. + assert(Inputs[0].isFilename() && "Invalid input."); + CmdArgs.push_back(TCArgs.MakeArgString(Inputs[0].getFilename())); + + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::None(), + TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())), + CmdArgs, Inputs)); + return; + } + // Add offload targets and inputs. for (unsigned I = 0; I < Inputs.size(); ++I) { // Get input's Offload Kind and ToolChain. diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 04349ff6af984..9d22cda217116 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -2408,6 +2408,13 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, // Enable compatibility mode for NSItemProviderCompletionHandler in // Foundation/NSItemProvider.h. CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking"); + + // Give static local variables in inline functions hidden visibility when + // -fvisibility-inlines-hidden is enabled. + if (!DriverArgs.getLastArgNoClaim( + options::OPT_fvisibility_inlines_hidden_static_local_var, + options::OPT_fno_visibility_inlines_hidden_static_local_var)) + CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var"); } DerivedArgList * diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 764eb0c965e05..447b4a9e87912 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -370,13 +370,16 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(std::string("-out:") + Output.getFilename())); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && - !C.getDriver().IsCLMode()) - CmdArgs.push_back("-defaultlib:libcmt"); + !C.getDriver().IsCLMode()) { + if (Args.hasArg(options::OPT_fsycl) && !Args.hasArg(options::OPT_nolibsycl)) + CmdArgs.push_back("-defaultlib:msvcrt"); + else + CmdArgs.push_back("-defaultlib:libcmt"); + } - if (!Args.hasArg(options::OPT_nostdlib) && Args.hasArg(options::OPT_fsycl) && - !Args.hasArg(options::OPT_nolibsycl)) { - if (Args.hasArg(options::OPT__SLASH_MDd) || - Args.hasArg(options::OPT__SLASH_MTd)) + if (!C.getDriver().IsCLMode() && !Args.hasArg(options::OPT_nostdlib) && + Args.hasArg(options::OPT_fsycl) && !Args.hasArg(options::OPT_nolibsycl)) { + if (Args.hasArg(options::OPT__SLASH_MDd)) CmdArgs.push_back("-defaultlib:sycld.lib"); else CmdArgs.push_back("-defaultlib:sycl.lib"); diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp index b61588399b9ba..4ed2ce29791c2 100644 --- a/clang/lib/Driver/ToolChains/SYCL.cpp +++ b/clang/lib/Driver/ToolChains/SYCL.cpp @@ -207,7 +207,8 @@ void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA, static const char *makeExeName(Compilation &C, StringRef Name) { llvm::SmallString<8> ExeName(Name); - if (C.getDriver().IsCLMode()) + const ToolChain *HostTC = C.getSingleOffloadToolChain(); + if (HostTC->getTriple().isWindowsMSVCEnvironment()) ExeName.append(".exe"); return C.getArgs().MakeArgString(ExeName); } @@ -233,7 +234,8 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C, // Add any FPGA library lists. These come in as special tempfile lists. CmdArgs.push_back(Args.MakeArgString(Twine("-library-list=") + Filename)); - else if (II.getType() == types::TY_FPGA_Dependencies) + else if (II.getType() == types::TY_FPGA_Dependencies || + II.getType() == types::TY_FPGA_Dependencies_List) FPGADepFiles.push_back(II); else CmdArgs.push_back(C.getArgs().MakeArgString(Filename)); @@ -287,6 +289,8 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C, for (unsigned I = 0; I < FPGADepFiles.size(); ++I) { if (I) DepOpt += ','; + if (FPGADepFiles[I].getType() == types::TY_FPGA_Dependencies_List) + DepOpt += "@"; DepOpt += FPGADepFiles[I].getFilename(); } CmdArgs.push_back(C.getArgs().MakeArgString(DepOpt)); diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index fe11cba9bfdf0..5dda2bda06b54 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -475,6 +475,7 @@ template <> struct MappingTraits { Style.AlwaysBreakBeforeMultilineStrings); IO.mapOptional("AlwaysBreakTemplateDeclarations", Style.AlwaysBreakTemplateDeclarations); + IO.mapOptional("AttributeMacros", Style.AttributeMacros); IO.mapOptional("BinPackArguments", Style.BinPackArguments); IO.mapOptional("BinPackParameters", Style.BinPackParameters); IO.mapOptional("BraceWrapping", Style.BraceWrapping); @@ -842,6 +843,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None; LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine; + LLVMStyle.AttributeMacros.push_back("__capability"); LLVMStyle.BinPackArguments = true; LLVMStyle.BinPackParameters = true; LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp index 4bc865b043fd2..8e4994f4c0d57 100644 --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -62,6 +62,7 @@ bool FormatToken::isSimpleTypeSpecifier() const { case tok::kw_char32_t: case tok::kw_typeof: case tok::kw_decltype: + case tok::kw__Atomic: return true; default: return false; diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index a54600a478a46..76ef99e72d58e 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -29,6 +29,7 @@ namespace format { TYPE(ArrayInitializerLSquare) \ TYPE(ArraySubscriptLSquare) \ TYPE(AttributeColon) \ + TYPE(AttributeMacro) \ TYPE(AttributeParen) \ TYPE(AttributeSquare) \ TYPE(BinaryOperator) \ @@ -100,6 +101,7 @@ namespace format { TYPE(TrailingAnnotation) \ TYPE(TrailingReturnArrow) \ TYPE(TrailingUnaryOperator) \ + TYPE(TypeDeclarationParen) \ TYPE(TypenameMacro) \ TYPE(UnaryOperator) \ TYPE(UntouchableMacroFunc) \ @@ -442,7 +444,8 @@ struct FormatToken { bool canBePointerOrReferenceQualifier() const { return isOneOf(tok::kw_const, tok::kw_restrict, tok::kw_volatile, tok::kw___attribute, tok::kw__Nonnull, tok::kw__Nullable, - tok::kw__Null_unspecified); + tok::kw__Null_unspecified, tok::kw___ptr32, tok::kw___ptr64, + TT_AttributeMacro); } /// Determine whether the token is a simple-type-specifier. @@ -523,7 +526,9 @@ struct FormatToken { case tok::kw_decltype: case tok::kw_noexcept: case tok::kw_static_assert: + case tok::kw__Atomic: case tok::kw___attribute: + case tok::kw___underlying_type: return true; default: return false; diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 1fd153d1112eb..f6db58acd8dbe 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -39,6 +39,8 @@ FormatTokenLexer::FormatTokenLexer( for (const std::string &ForEachMacro : Style.ForEachMacros) Macros.insert({&IdentTable.get(ForEachMacro), TT_ForEachMacro}); + for (const std::string &AttributeMacro : Style.AttributeMacros) + Macros.insert({&IdentTable.get(AttributeMacro), TT_AttributeMacro}); for (const std::string &StatementMacro : Style.StatementMacros) Macros.insert({&IdentTable.get(StatementMacro), TT_StatementMacro}); for (const std::string &TypenameMacro : Style.TypenameMacros) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a9077500e041f..5dd6a7a9da40b 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -185,6 +185,8 @@ class AnnotatingParser { if (!CurrentToken) return false; FormatToken *Left = CurrentToken->Previous; + FormatToken *PrevNonComment = + Left ? Left->getPreviousNonComment() : nullptr; Left->ParentBracket = Contexts.back().ContextKind; ScopedContextCreator ContextCreator(*this, tok::l_paren, 1); @@ -216,9 +218,8 @@ class AnnotatingParser { // export type X = (...); Contexts.back().IsExpression = false; } else if (Left->Previous && - (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype, - tok::kw_while, tok::l_paren, - tok::comma) || + (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_while, + tok::l_paren, tok::comma) || Left->Previous->isIf() || Left->Previous->is(TT_BinaryOperator))) { // static_assert, if and while usually contain expressions. @@ -242,8 +243,16 @@ class AnnotatingParser { } else if (Contexts[Contexts.size() - 2].CaretFound) { // This is the parameter list of an ObjC block. Contexts.back().IsExpression = false; - } else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) { + } else if (PrevNonComment && PrevNonComment->is(tok::kw___attribute)) { Left->setType(TT_AttributeParen); + } else if (PrevNonComment && + PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype, + tok::kw_typeof, tok::kw__Atomic, + tok::kw___underlying_type)) { + Left->setType(TT_TypeDeclarationParen); + // decltype() and typeof() usually contain expressions. + if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof)) + Contexts.back().IsExpression = true; } else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) { // The first argument to a foreach macro is a declaration. Contexts.back().IsForEachMacro = true; @@ -335,6 +344,8 @@ class AnnotatingParser { if (Left->is(TT_AttributeParen)) CurrentToken->setType(TT_AttributeParen); + if (Left->is(TT_TypeDeclarationParen)) + CurrentToken->setType(TT_TypeDeclarationParen); if (Left->Previous && Left->Previous->is(TT_JavaAnnotation)) CurrentToken->setType(TT_JavaAnnotation); if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation)) @@ -940,9 +951,9 @@ class AnnotatingParser { return false; if (Line.MustBeDeclaration && Contexts.size() == 1 && !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) && - (!Tok->Previous || - !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute, - TT_LeadingJavaAnnotation))) + !Tok->is(TT_TypeDeclarationParen) && + (!Tok->Previous || !Tok->Previous->isOneOf(tok::kw___attribute, + TT_LeadingJavaAnnotation))) Line.MightBeFunctionDecl = true; break; case tok::l_square: @@ -1333,11 +1344,12 @@ class AnnotatingParser { // Reset token type in case we have already looked at it and then // recovered from an error (e.g. failure to find the matching >). if (!CurrentToken->isOneOf( - TT_LambdaLSquare, TT_LambdaLBrace, TT_ForEachMacro, - TT_TypenameMacro, TT_FunctionLBrace, TT_ImplicitStringLiteral, - TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow, TT_NamespaceMacro, - TT_OverloadedOperator, TT_RegexLiteral, TT_TemplateString, - TT_ObjCStringLiteral, TT_UntouchableMacroFunc)) + TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, + TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace, + TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_JsFatArrow, + TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator, + TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral, + TT_UntouchableMacroFunc)) CurrentToken->setType(TT_Unknown); CurrentToken->Role.reset(); CurrentToken->MatchingParen = nullptr; @@ -1753,9 +1765,8 @@ class AnnotatingParser { PreviousNotConst->MatchingParen->Previous->isNot(tok::period) && PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template); - if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen && - PreviousNotConst->MatchingParen->Previous && - PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype)) + if (PreviousNotConst->is(tok::r_paren) && + PreviousNotConst->is(TT_TypeDeclarationParen)) return true; return (!IsPPKeyword && @@ -1840,6 +1851,12 @@ class AnnotatingParser { T = T->MatchingParen->Previous->Previous; continue; } + } else if (T->is(TT_AttributeSquare)) { + // Handle `x = (foo *[[clang::foo]])&v;`: + if (T->MatchingParen && T->MatchingParen->Previous) { + T = T->MatchingParen->Previous; + continue; + } } else if (T->canBePointerOrReferenceQualifier()) { T = T->Previous; continue; @@ -1848,9 +1865,11 @@ class AnnotatingParser { } return T && T->is(TT_PointerOrReference); }; - bool ParensAreType = !Tok.Previous || Tok.Previous->is(TT_TemplateCloser) || - Tok.Previous->isSimpleTypeSpecifier() || - IsQualifiedPointerOrReference(Tok.Previous); + bool ParensAreType = + !Tok.Previous || + Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) || + Tok.Previous->isSimpleTypeSpecifier() || + IsQualifiedPointerOrReference(Tok.Previous); bool ParensCouldEndDecl = Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater); if (ParensAreType && !ParensCouldEndDecl) @@ -1918,6 +1937,9 @@ class AnnotatingParser { if (PrevToken->is(tok::coloncolon)) return TT_PointerOrReference; + if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen)) + return TT_PointerOrReference; + if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace, tok::comma, tok::semi, tok::kw_return, tok::colon, tok::equal, tok::kw_delete, tok::kw_sizeof, @@ -1933,15 +1955,6 @@ class AnnotatingParser { if (NextToken->isOneOf(tok::comma, tok::semi)) return TT_PointerOrReference; - if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) { - FormatToken *TokenBeforeMatchingParen = - PrevToken->MatchingParen->getPreviousNonComment(); - if (TokenBeforeMatchingParen && - TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype, - TT_TypenameMacro)) - return TT_PointerOrReference; - } - if (PrevToken->Tok.isLiteral() || PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true, tok::kw_false, tok::r_brace) || @@ -2387,6 +2400,8 @@ static bool isFunctionDeclarationName(const FormatToken &Current, return true; for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen; Tok = Tok->Next) { + if (Tok->is(TT_TypeDeclarationParen)) + return true; if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) { Tok = Tok->MatchingParen; continue; @@ -2835,9 +2850,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return true; FormatToken *TokenBeforeMatchingParen = Left.MatchingParen->getPreviousNonComment(); - if (!TokenBeforeMatchingParen || - !TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype, - TT_TypenameMacro)) + if (!TokenBeforeMatchingParen || !Left.is(TT_TypeDeclarationParen)) return true; } return (Left.Tok.isLiteral() || @@ -3935,7 +3948,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, if (Left.is(tok::equal) && Right.is(tok::l_brace) && !Style.Cpp11BracedListStyle) return false; - if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen)) + if (Left.is(tok::l_paren) && + Left.isOneOf(TT_AttributeParen, TT_TypeDeclarationParen)) return false; if (Left.is(tok::l_paren) && Left.Previous && (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 392ba0f30f105..794a5c96b0f4a 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -823,14 +823,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists)) Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists; - // ESIMD GPU Back-end requires optimized IR - bool IsSyclESIMD = Args.hasFlag(options::OPT_fsycl_esimd, - options::OPT_fno_sycl_esimd, false); - Opts.DisableLLVMPasses = Args.hasArg(OPT_disable_llvm_passes) || (Args.hasArg(OPT_fsycl_is_device) && Triple.isSPIR() && - Args.hasArg(OPT_fno_sycl_early_optimizations) && !IsSyclESIMD); + Args.hasArg(OPT_fno_sycl_early_optimizations)); Opts.DisableLifetimeMarkers = Args.hasArg(OPT_disable_lifetimemarkers); const llvm::Triple::ArchType DebugEntryValueArchs[] = { @@ -1041,7 +1037,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.ThinLinkBitcodeFile = std::string(Args.getLastArgValue(OPT_fthin_link_bitcode_EQ)); - Opts.HeapProf = Args.hasArg(OPT_fmemprof); + Opts.HeapProf = Args.hasArg(OPT_fmemory_profile); Opts.MSVolatile = Args.hasArg(OPT_fms_volatile); @@ -2612,6 +2608,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.SYCLValueFitInMaxInt = Args.hasFlag(options::OPT_fsycl_id_queries_fit_in_int, options::OPT_fno_sycl_id_queries_fit_in_int, false); + Opts.SYCLIntHeader = + std::string(Args.getLastArgValue(OPT_fsycl_int_header)); } Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header); @@ -2672,8 +2670,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Diags.Report(diag::warn_ignored_hip_only_option) << Args.getLastArg(OPT_gpu_max_threads_per_block_EQ)->getAsString(Args); - Opts.SYCLIntHeader = std::string(Args.getLastArgValue(OPT_fsycl_int_header)); - if (Opts.ObjC) { if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) { StringRef value = arg->getValue(); @@ -2793,6 +2789,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fvisibility_inlines_hidden)) Opts.InlineVisibilityHidden = 1; + if (Args.hasArg(OPT_fvisibility_inlines_hidden_static_local_var)) + Opts.VisibilityInlinesHiddenStaticLocalVar = 1; + if (Args.hasArg(OPT_fvisibility_global_new_delete_hidden)) Opts.GlobalAllocationFunctionVisibilityHidden = 1; diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index 927f25751664a..22744adefbefd 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -1766,36 +1766,12 @@ vec_cmpne(vector unsigned int __a, vector unsigned int __b) { (vector int)__b); } -static __inline__ vector bool long long __ATTRS_o_ai -vec_cmpne(vector bool long long __a, vector bool long long __b) { - return (vector bool long long) - ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b)); -} - -static __inline__ vector bool long long __ATTRS_o_ai -vec_cmpne(vector signed long long __a, vector signed long long __b) { - return (vector bool long long) - ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b)); -} - -static __inline__ vector bool long long __ATTRS_o_ai -vec_cmpne(vector unsigned long long __a, vector unsigned long long __b) { - return (vector bool long long) - ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b)); -} - static __inline__ vector bool int __ATTRS_o_ai vec_cmpne(vector float __a, vector float __b) { return (vector bool int)__builtin_altivec_vcmpnew((vector int)__a, (vector int)__b); } -static __inline__ vector bool long long __ATTRS_o_ai -vec_cmpne(vector double __a, vector double __b) { - return (vector bool long long) - ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b)); -} - /* vec_cmpnez */ static __inline__ vector bool char __ATTRS_o_ai @@ -1900,6 +1876,86 @@ vec_parity_lsbb(vector signed long long __a) { return __builtin_altivec_vprtybd(__a); } +#else +/* vec_cmpne */ + +static __inline__ vector bool char __ATTRS_o_ai +vec_cmpne(vector bool char __a, vector bool char __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool char __ATTRS_o_ai +vec_cmpne(vector signed char __a, vector signed char __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool char __ATTRS_o_ai +vec_cmpne(vector unsigned char __a, vector unsigned char __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool short __ATTRS_o_ai +vec_cmpne(vector bool short __a, vector bool short __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool short __ATTRS_o_ai +vec_cmpne(vector signed short __a, vector signed short __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool short __ATTRS_o_ai +vec_cmpne(vector unsigned short __a, vector unsigned short __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool int __ATTRS_o_ai +vec_cmpne(vector bool int __a, vector bool int __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool int __ATTRS_o_ai +vec_cmpne(vector signed int __a, vector signed int __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool int __ATTRS_o_ai +vec_cmpne(vector unsigned int __a, vector unsigned int __b) { + return ~(vec_cmpeq(__a, __b)); +} + +static __inline__ vector bool int __ATTRS_o_ai +vec_cmpne(vector float __a, vector float __b) { + return ~(vec_cmpeq(__a, __b)); +} +#endif + +#ifdef __POWER8_VECTOR__ +static __inline__ vector bool long long __ATTRS_o_ai +vec_cmpne(vector bool long long __a, vector bool long long __b) { + return (vector bool long long) + ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b)); +} + +static __inline__ vector bool long long __ATTRS_o_ai +vec_cmpne(vector signed long long __a, vector signed long long __b) { + return (vector bool long long) + ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b)); +} + +static __inline__ vector bool long long __ATTRS_o_ai +vec_cmpne(vector unsigned long long __a, vector unsigned long long __b) { + return (vector bool long long) + ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b)); +} +#endif + +#ifdef __VSX__ +static __inline__ vector bool long long __ATTRS_o_ai +vec_cmpne(vector double __a, vector double __b) { + return (vector bool long long) + ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b)); +} #endif /* vec_cmpgt */ @@ -2702,67 +2758,67 @@ vec_insert_exp(vector unsigned int __a, vector unsigned int __b) { } #if defined(__powerpc64__) -static __inline__ vector signed char __ATTRS_o_ai vec_xl_len(signed char *__a, +static __inline__ vector signed char __ATTRS_o_ai vec_xl_len(const signed char *__a, size_t __b) { return (vector signed char)__builtin_vsx_lxvl(__a, (__b << 56)); } static __inline__ vector unsigned char __ATTRS_o_ai -vec_xl_len(unsigned char *__a, size_t __b) { +vec_xl_len(const unsigned char *__a, size_t __b) { return (vector unsigned char)__builtin_vsx_lxvl(__a, (__b << 56)); } -static __inline__ vector signed short __ATTRS_o_ai vec_xl_len(signed short *__a, +static __inline__ vector signed short __ATTRS_o_ai vec_xl_len(const signed short *__a, size_t __b) { return (vector signed short)__builtin_vsx_lxvl(__a, (__b << 56)); } static __inline__ vector unsigned short __ATTRS_o_ai -vec_xl_len(unsigned short *__a, size_t __b) { +vec_xl_len(const unsigned short *__a, size_t __b) { return (vector unsigned short)__builtin_vsx_lxvl(__a, (__b << 56)); } -static __inline__ vector signed int __ATTRS_o_ai vec_xl_len(signed int *__a, +static __inline__ vector signed int __ATTRS_o_ai vec_xl_len(const signed int *__a, size_t __b) { return (vector signed int)__builtin_vsx_lxvl(__a, (__b << 56)); } -static __inline__ vector unsigned int __ATTRS_o_ai vec_xl_len(unsigned int *__a, +static __inline__ vector unsigned int __ATTRS_o_ai vec_xl_len(const unsigned int *__a, size_t __b) { return (vector unsigned int)__builtin_vsx_lxvl(__a, (__b << 56)); } -static __inline__ vector float __ATTRS_o_ai vec_xl_len(float *__a, size_t __b) { +static __inline__ vector float __ATTRS_o_ai vec_xl_len(const float *__a, size_t __b) { return (vector float)__builtin_vsx_lxvl(__a, (__b << 56)); } static __inline__ vector signed __int128 __ATTRS_o_ai -vec_xl_len(signed __int128 *__a, size_t __b) { +vec_xl_len(const signed __int128 *__a, size_t __b) { return (vector signed __int128)__builtin_vsx_lxvl(__a, (__b << 56)); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_len(unsigned __int128 *__a, size_t __b) { +vec_xl_len(const unsigned __int128 *__a, size_t __b) { return (vector unsigned __int128)__builtin_vsx_lxvl(__a, (__b << 56)); } static __inline__ vector signed long long __ATTRS_o_ai -vec_xl_len(signed long long *__a, size_t __b) { +vec_xl_len(const signed long long *__a, size_t __b) { return (vector signed long long)__builtin_vsx_lxvl(__a, (__b << 56)); } static __inline__ vector unsigned long long __ATTRS_o_ai -vec_xl_len(unsigned long long *__a, size_t __b) { +vec_xl_len(const unsigned long long *__a, size_t __b) { return (vector unsigned long long)__builtin_vsx_lxvl(__a, (__b << 56)); } -static __inline__ vector double __ATTRS_o_ai vec_xl_len(double *__a, +static __inline__ vector double __ATTRS_o_ai vec_xl_len(const double *__a, size_t __b) { return (vector double)__builtin_vsx_lxvl(__a, (__b << 56)); } static __inline__ vector unsigned char __ATTRS_o_ai -vec_xl_len_r(unsigned char *__a, size_t __b) { +vec_xl_len_r(const unsigned char *__a, size_t __b) { vector unsigned char __res = (vector unsigned char)__builtin_vsx_lxvll(__a, (__b << 56)); #ifdef __LITTLE_ENDIAN__ @@ -5487,6 +5543,16 @@ vec_msum(vector unsigned short __a, vector unsigned short __b, return __builtin_altivec_vmsumuhm(__a, __b, __c); } +/* vec_msumc */ + +#ifdef __POWER10_VECTOR__ +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_msumc(vector unsigned long long __a, vector unsigned long long __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vmsumcud(__a, __b, __c); +} +#endif + /* vec_vmsummbm */ static __inline__ vector int __attribute__((__always_inline__)) @@ -5713,6 +5779,26 @@ vec_mule(vector unsigned int __a, vector unsigned int __b) { } #endif +#ifdef __POWER10_VECTOR__ +static __inline__ vector signed __int128 __ATTRS_o_ai +vec_mule(vector signed long long __a, vector signed long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosd(__a, __b); +#else + return __builtin_altivec_vmulesd(__a, __b); +#endif +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_mule(vector unsigned long long __a, vector unsigned long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuloud(__a, __b); +#else + return __builtin_altivec_vmuleud(__a, __b); +#endif +} +#endif + /* vec_vmulesb */ static __inline__ vector short __attribute__((__always_inline__)) @@ -5839,6 +5925,26 @@ vec_mulo(vector unsigned int __a, vector unsigned int __b) { } #endif +#ifdef __POWER10_VECTOR__ +static __inline__ vector signed __int128 __ATTRS_o_ai +vec_mulo(vector signed long long __a, vector signed long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesd(__a, __b); +#else + return __builtin_altivec_vmulosd(__a, __b); +#endif +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_mulo(vector unsigned long long __a, vector unsigned long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleud(__a, __b); +#else + return __builtin_altivec_vmuloud(__a, __b); +#endif +} +#endif + /* vec_vmulosb */ static __inline__ vector short __attribute__((__always_inline__)) @@ -16397,41 +16503,41 @@ typedef vector unsigned int unaligned_vec_uint __attribute__((aligned(1))); typedef vector float unaligned_vec_float __attribute__((aligned(1))); static inline __ATTRS_o_ai vector signed char vec_xl(signed long long __offset, - signed char *__ptr) { + const signed char *__ptr) { return *(unaligned_vec_schar *)(__ptr + __offset); } static inline __ATTRS_o_ai vector unsigned char -vec_xl(signed long long __offset, unsigned char *__ptr) { +vec_xl(signed long long __offset, const unsigned char *__ptr) { return *(unaligned_vec_uchar*)(__ptr + __offset); } static inline __ATTRS_o_ai vector signed short vec_xl(signed long long __offset, - signed short *__ptr) { + const signed short *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_sshort *)__addr; } static inline __ATTRS_o_ai vector unsigned short -vec_xl(signed long long __offset, unsigned short *__ptr) { +vec_xl(signed long long __offset, const unsigned short *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_ushort *)__addr; } static inline __ATTRS_o_ai vector signed int vec_xl(signed long long __offset, - signed int *__ptr) { + const signed int *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_sint *)__addr; } static inline __ATTRS_o_ai vector unsigned int vec_xl(signed long long __offset, - unsigned int *__ptr) { + const unsigned int *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_uint *)__addr; } static inline __ATTRS_o_ai vector float vec_xl(signed long long __offset, - float *__ptr) { + const float *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_float *)__addr; } @@ -16442,19 +16548,19 @@ typedef vector unsigned long long unaligned_vec_ull __attribute__((aligned(1))); typedef vector double unaligned_vec_double __attribute__((aligned(1))); static inline __ATTRS_o_ai vector signed long long -vec_xl(signed long long __offset, signed long long *__ptr) { +vec_xl(signed long long __offset, const signed long long *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_sll *)__addr; } static inline __ATTRS_o_ai vector unsigned long long -vec_xl(signed long long __offset, unsigned long long *__ptr) { +vec_xl(signed long long __offset, const unsigned long long *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_ull *)__addr; } static inline __ATTRS_o_ai vector double vec_xl(signed long long __offset, - double *__ptr) { + const double *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_double *)__addr; } @@ -16465,13 +16571,13 @@ typedef vector signed __int128 unaligned_vec_si128 __attribute__((aligned(1))); typedef vector unsigned __int128 unaligned_vec_ui128 __attribute__((aligned(1))); static inline __ATTRS_o_ai vector signed __int128 -vec_xl(signed long long __offset, signed __int128 *__ptr) { +vec_xl(signed long long __offset, const signed __int128 *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_si128 *)__addr; } static inline __ATTRS_o_ai vector unsigned __int128 -vec_xl(signed long long __offset, unsigned __int128 *__ptr) { +vec_xl(signed long long __offset, const unsigned __int128 *__ptr) { signed char *__addr = (signed char *)__ptr + __offset; return *(unaligned_vec_ui128 *)__addr; } @@ -16481,71 +16587,71 @@ vec_xl(signed long long __offset, unsigned __int128 *__ptr) { #ifdef __LITTLE_ENDIAN__ static __inline__ vector signed char __ATTRS_o_ai -vec_xl_be(signed long long __offset, signed char *__ptr) { +vec_xl_be(signed long long __offset, const signed char *__ptr) { vector signed char __vec = (vector signed char)__builtin_vsx_lxvd2x_be(__offset, __ptr); return __builtin_shufflevector(__vec, __vec, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); } static __inline__ vector unsigned char __ATTRS_o_ai -vec_xl_be(signed long long __offset, unsigned char *__ptr) { +vec_xl_be(signed long long __offset, const unsigned char *__ptr) { vector unsigned char __vec = (vector unsigned char)__builtin_vsx_lxvd2x_be(__offset, __ptr); return __builtin_shufflevector(__vec, __vec, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); } static __inline__ vector signed short __ATTRS_o_ai -vec_xl_be(signed long long __offset, signed short *__ptr) { +vec_xl_be(signed long long __offset, const signed short *__ptr) { vector signed short __vec = (vector signed short)__builtin_vsx_lxvd2x_be(__offset, __ptr); return __builtin_shufflevector(__vec, __vec, 3, 2, 1, 0, 7, 6, 5, 4); } static __inline__ vector unsigned short __ATTRS_o_ai -vec_xl_be(signed long long __offset, unsigned short *__ptr) { +vec_xl_be(signed long long __offset, const unsigned short *__ptr) { vector unsigned short __vec = (vector unsigned short)__builtin_vsx_lxvd2x_be(__offset, __ptr); return __builtin_shufflevector(__vec, __vec, 3, 2, 1, 0, 7, 6, 5, 4); } static __inline__ vector signed int __ATTRS_o_ai -vec_xl_be(signed long long __offset, signed int *__ptr) { +vec_xl_be(signed long long __offset, const signed int *__ptr) { return (vector signed int)__builtin_vsx_lxvw4x_be(__offset, __ptr); } static __inline__ vector unsigned int __ATTRS_o_ai -vec_xl_be(signed long long __offset, unsigned int *__ptr) { +vec_xl_be(signed long long __offset, const unsigned int *__ptr) { return (vector unsigned int)__builtin_vsx_lxvw4x_be(__offset, __ptr); } static __inline__ vector float __ATTRS_o_ai -vec_xl_be(signed long long __offset, float *__ptr) { +vec_xl_be(signed long long __offset, const float *__ptr) { return (vector float)__builtin_vsx_lxvw4x_be(__offset, __ptr); } #ifdef __VSX__ static __inline__ vector signed long long __ATTRS_o_ai -vec_xl_be(signed long long __offset, signed long long *__ptr) { +vec_xl_be(signed long long __offset, const signed long long *__ptr) { return (vector signed long long)__builtin_vsx_lxvd2x_be(__offset, __ptr); } static __inline__ vector unsigned long long __ATTRS_o_ai -vec_xl_be(signed long long __offset, unsigned long long *__ptr) { +vec_xl_be(signed long long __offset, const unsigned long long *__ptr) { return (vector unsigned long long)__builtin_vsx_lxvd2x_be(__offset, __ptr); } static __inline__ vector double __ATTRS_o_ai -vec_xl_be(signed long long __offset, double *__ptr) { +vec_xl_be(signed long long __offset, const double *__ptr) { return (vector double)__builtin_vsx_lxvd2x_be(__offset, __ptr); } #endif #if defined(__POWER8_VECTOR__) && defined(__powerpc64__) static __inline__ vector signed __int128 __ATTRS_o_ai -vec_xl_be(signed long long __offset, signed __int128 *__ptr) { +vec_xl_be(signed long long __offset, const signed __int128 *__ptr) { return vec_xl(__offset, __ptr); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_be(signed long long __offset, unsigned __int128 *__ptr) { +vec_xl_be(signed long long __offset, const unsigned __int128 *__ptr) { return vec_xl(__offset, __ptr); } #endif @@ -16558,44 +16664,44 @@ vec_xl_be(signed long long __offset, unsigned __int128 *__ptr) { /* vect_xl_sext */ static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_sext(signed long long __offset, signed char *__pointer) { +vec_xl_sext(signed long long __offset, const signed char *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_sext(signed long long __offset, signed short *__pointer) { +vec_xl_sext(signed long long __offset, const signed short *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_sext(signed long long __offset, signed int *__pointer) { +vec_xl_sext(signed long long __offset, const signed int *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_sext(signed long long __offset, signed long long *__pointer) { +vec_xl_sext(signed long long __offset, const signed long long *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } /* vec_xl_zext */ static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_zext(signed long long __offset, unsigned char *__pointer) { +vec_xl_zext(signed long long __offset, const unsigned char *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_zext(signed long long __offset, unsigned short *__pointer) { +vec_xl_zext(signed long long __offset, const unsigned short *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_zext(signed long long __offset, unsigned int *__pointer) { +vec_xl_zext(signed long long __offset, const unsigned int *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } static __inline__ vector unsigned __int128 __ATTRS_o_ai -vec_xl_zext(signed long long __offset, unsigned long long *__pointer) { +vec_xl_zext(signed long long __offset, const unsigned long long *__pointer) { return (vector unsigned __int128)*(__pointer + __offset); } @@ -16935,6 +17041,33 @@ vec_extractm(vector unsigned __int128 __a) { return __builtin_altivec_vextractqm(__a); } +/* vec_expandm */ + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_expandm(vector unsigned char __a) { + return __builtin_altivec_vexpandbm(__a); +} + +static __inline__ vector unsigned short __ATTRS_o_ai +vec_expandm(vector unsigned short __a) { + return __builtin_altivec_vexpandhm(__a); +} + +static __inline__ vector unsigned int __ATTRS_o_ai +vec_expandm(vector unsigned int __a) { + return __builtin_altivec_vexpandwm(__a); +} + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_expandm(vector unsigned long long __a) { + return __builtin_altivec_vexpanddm(__a); +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_expandm(vector unsigned __int128 __a) { + return __builtin_altivec_vexpandqm(__a); +} + /* vec_pdep */ static __inline__ vector unsigned long long __ATTRS_o_ai diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 6402b31d00b29..572fc7115b879 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -135,6 +135,14 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { } }; +/// Handler for "\#pragma STDC FENV_ROUND ...". +struct PragmaSTDC_FENV_ROUNDHandler : public PragmaHandler { + PragmaSTDC_FENV_ROUNDHandler() : PragmaHandler("FENV_ROUND") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, + Token &Tok) override; +}; + /// PragmaSTDC_UnknownHandler - "\#pragma STDC ...". struct PragmaSTDC_UnknownHandler : public PragmaHandler { PragmaSTDC_UnknownHandler() = default; @@ -312,8 +320,11 @@ void Parser::initializePragmaHandlers() { FPContractHandler = std::make_unique(); PP.AddPragmaHandler("STDC", FPContractHandler.get()); - STDCFENVHandler = std::make_unique(); - PP.AddPragmaHandler("STDC", STDCFENVHandler.get()); + STDCFenvAccessHandler = std::make_unique(); + PP.AddPragmaHandler("STDC", STDCFenvAccessHandler.get()); + + STDCFenvRoundHandler = std::make_unique(); + PP.AddPragmaHandler("STDC", STDCFenvRoundHandler.get()); STDCCXLIMITHandler = std::make_unique(); PP.AddPragmaHandler("STDC", STDCCXLIMITHandler.get()); @@ -485,8 +496,11 @@ void Parser::resetPragmaHandlers() { PP.RemovePragmaHandler("STDC", FPContractHandler.get()); FPContractHandler.reset(); - PP.RemovePragmaHandler("STDC", STDCFENVHandler.get()); - STDCFENVHandler.reset(); + PP.RemovePragmaHandler("STDC", STDCFenvAccessHandler.get()); + STDCFenvAccessHandler.reset(); + + PP.RemovePragmaHandler("STDC", STDCFenvRoundHandler.get()); + STDCFenvRoundHandler.reset(); PP.RemovePragmaHandler("STDC", STDCCXLIMITHandler.get()); STDCCXLIMITHandler.reset(); @@ -697,6 +711,14 @@ void Parser::HandlePragmaFEnvAccess() { Actions.ActOnPragmaFEnvAccess(PragmaLoc, IsEnabled); } +void Parser::HandlePragmaFEnvRound() { + assert(Tok.is(tok::annot_pragma_fenv_round)); + auto RM = static_cast( + reinterpret_cast(Tok.getAnnotationValue())); + + SourceLocation PragmaLoc = ConsumeAnnotationToken(); + Actions.setRoundingMode(PragmaLoc, RM); +} StmtResult Parser::HandlePragmaCaptured() { @@ -2929,6 +2951,56 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP, /*DisableMacroExpansion=*/false, /*IsReinject=*/false); } +void PragmaSTDC_FENV_ROUNDHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducer Introducer, + Token &Tok) { + Token PragmaName = Tok; + SmallVector TokenList; + + PP.Lex(Tok); + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) + << PragmaName.getIdentifierInfo()->getName(); + return; + } + IdentifierInfo *II = Tok.getIdentifierInfo(); + + auto RM = + llvm::StringSwitch(II->getName()) + .Case("FE_TOWARDZERO", llvm::RoundingMode::TowardZero) + .Case("FE_TONEAREST", llvm::RoundingMode::NearestTiesToEven) + .Case("FE_UPWARD", llvm::RoundingMode::TowardPositive) + .Case("FE_DOWNWARD", llvm::RoundingMode::TowardNegative) + .Case("FE_TONEARESTFROMZERO", llvm::RoundingMode::NearestTiesToAway) + .Case("FE_DYNAMIC", llvm::RoundingMode::Dynamic) + .Default(llvm::RoundingMode::Invalid); + if (RM == llvm::RoundingMode::Invalid) { + PP.Diag(Tok.getLocation(), diag::warn_stdc_unknown_rounding_mode); + return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::eod)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) + << "STDC FENV_ROUND"; + return; + } + + // Until the pragma is fully implemented, issue a warning. + PP.Diag(Tok.getLocation(), diag::warn_stdc_fenv_round_not_supported); + + MutableArrayRef Toks(PP.getPreprocessorAllocator().Allocate(1), + 1); + Toks[0].startToken(); + Toks[0].setKind(tok::annot_pragma_fenv_round); + Toks[0].setLocation(Tok.getLocation()); + Toks[0].setAnnotationEndLoc(Tok.getLocation()); + Toks[0].setAnnotationValue( + reinterpret_cast(static_cast(RM))); + PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true, + /*IsReinject=*/false); +} + void Parser::HandlePragmaFP() { assert(Tok.is(tok::annot_pragma_fp)); auto *AnnotValue = diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 48a583b8c67db..dc946bd94bbba 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -370,6 +370,12 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( HandlePragmaFEnvAccess(); return StmtEmpty(); + case tok::annot_pragma_fenv_round: + ProhibitAttributes(Attrs); + Diag(Tok, diag::err_pragma_file_or_compound_scope) << "STDC FENV_ROUND"; + ConsumeAnnotationToken(); + return StmtError(); + case tok::annot_pragma_float_control: ProhibitAttributes(Attrs); Diag(Tok, diag::err_pragma_file_or_compound_scope) << "float_control"; @@ -944,6 +950,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() { case tok::annot_pragma_fenv_access: HandlePragmaFEnvAccess(); break; + case tok::annot_pragma_fenv_round: + HandlePragmaFEnvRound(); + break; case tok::annot_pragma_float_control: HandlePragmaFloatControl(); break; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index c72ffde8fc263..109f24425777d 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -783,6 +783,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, case tok::annot_pragma_fenv_access: HandlePragmaFEnvAccess(); return nullptr; + case tok::annot_pragma_fenv_round: + HandlePragmaFEnvRound(); + return nullptr; case tok::annot_pragma_float_control: HandlePragmaFloatControl(); return nullptr; diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index e34f7371506dd..bd5fc586b6af7 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -979,6 +979,11 @@ void Sema::ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled) { } void Sema::setRoundingMode(SourceLocation Loc, llvm::RoundingMode FPR) { + // C2x: 7.6.2p3 If the FE_DYNAMIC mode is specified and FENV_ACCESS is "off", + // the translator may assume that the default rounding mode is in effect. + if (FPR == llvm::RoundingMode::Dynamic && !CurFPFeatures.getAllowFEnvAccess()) + FPR = llvm::RoundingMode::NearestTiesToEven; + FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); NewFPFeatures.setRoundingModeOverride(FPR); FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a036c520211a3..caec2fdcb9b10 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3215,8 +3215,12 @@ static void adjustDeclContextForDeclaratorDecl(DeclaratorDecl *NewD, template static void checkDimensionsAndSetDiagnostics(Sema &S, FunctionDecl *New, FunctionDecl *Old) { - AttributeType *NewDeclAttr = New->getAttr(); - AttributeType *OldDeclAttr = Old->getAttr(); + const auto *NewDeclAttr = New->getAttr(); + const auto *OldDeclAttr = Old->getAttr(); + + if (!NewDeclAttr || !OldDeclAttr) + return; + if ((NewDeclAttr->getXDim() != OldDeclAttr->getXDim()) || (NewDeclAttr->getYDim() != OldDeclAttr->getYDim()) || (NewDeclAttr->getZDim() != OldDeclAttr->getZDim())) { @@ -3302,12 +3306,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, } } - if (New->hasAttr() && - Old->hasAttr()) checkDimensionsAndSetDiagnostics(*this, New, Old); - if (New->hasAttr() && - Old->hasAttr()) checkDimensionsAndSetDiagnostics(*this, New, Old); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 9aabf4aae0b4f..f3b9fb4023b87 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2979,31 +2979,6 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { } // Handles intel_reqd_sub_group_size. -void Sema::addIntelReqdSubGroupSizeAttr(Decl *D, - const AttributeCommonInfo &Attr, - Expr *E) { - if (!E) - return; - - if (!E->isInstantiationDependent()) { - Optional ArgVal = E->getIntegerConstantExpr(getASTContext()); - if (!ArgVal) { - Diag(E->getExprLoc(), diag::err_attribute_argument_type) - << Attr.getAttrName() << AANT_ArgumentIntegerConstant - << E->getSourceRange(); - return; - } - int32_t ArgInt = ArgVal->getSExtValue(); - if (ArgInt <= 0) { - Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) - << Attr.getAttrName() << /*positive*/ 0; - return; - } - } - - D->addAttr(::new (Context) IntelReqdSubGroupSizeAttr(Context, Attr, E)); -} - static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { if (S.LangOpts.SYCLIsHost) return; @@ -3013,7 +2988,7 @@ static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { if (D->getAttr()) S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL; - S.addIntelReqdSubGroupSizeAttr(D, AL, E); + S.addIntelSYCLSingleArgFunctionAttr(D, AL, E); } // Handles num_simd_work_items. @@ -3022,23 +2997,13 @@ static void handleNumSimdWorkItemsAttr(Sema &S, Decl *D, if (D->isInvalidDecl()) return; - uint32_t NumSimdWorkItems = 0; - const Expr *E = Attr.getArgAsExpr(0); - if (!checkUInt32Argument(S, Attr, E, NumSimdWorkItems, 0, - /*StrictlyUnsigned=*/true)) - return; - - if (NumSimdWorkItems == 0) { - S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero) - << Attr << E->getSourceRange(); - return; - } + Expr *E = Attr.getArgAsExpr(0); if (D->getAttr()) S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr; - D->addAttr(::new (S.Context) SYCLIntelNumSimdWorkItemsAttr( - S.Context, Attr, NumSimdWorkItems)); + S.addIntelSYCLSingleArgFunctionAttr(D, Attr, + E); } // Handles max_global_work_dim. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index db3a80ae876ac..75200cdfd64ef 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4615,8 +4615,8 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, << SourceRange(base->getBeginLoc(), rbLoc); return ExprError(); } - // If the base is either a MatrixSubscriptExpr or a matrix type, try to create - // a new MatrixSubscriptExpr. + // If the base is a MatrixSubscriptExpr, try to create a new + // MatrixSubscriptExpr. auto *matSubscriptE = dyn_cast(base); if (matSubscriptE) { if (CheckAndReportCommaError(idx)) @@ -4627,34 +4627,13 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, return CreateBuiltinMatrixSubscriptExpr( matSubscriptE->getBase(), matSubscriptE->getRowIdx(), idx, rbLoc); } - Expr *matrixBase = base; - bool IsMSPropertySubscript = isMSPropertySubscriptExpr(*this, base); - if (!IsMSPropertySubscript) { - ExprResult result = CheckPlaceholderExpr(base); - if (!result.isInvalid()) - matrixBase = result.get(); - } - if (matrixBase->getType()->isMatrixType()) { - if (CheckAndReportCommaError(idx)) - return ExprError(); - - return CreateBuiltinMatrixSubscriptExpr(matrixBase, idx, nullptr, rbLoc); - } - - // A comma-expression as the index is deprecated in C++2a onwards. - if (getLangOpts().CPlusPlus20 && - ((isa(idx) && cast(idx)->isCommaOp()) || - (isa(idx) && - cast(idx)->getOperator() == OO_Comma))) { - Diag(idx->getExprLoc(), diag::warn_deprecated_comma_subscript) - << SourceRange(base->getBeginLoc(), rbLoc); - } // Handle any non-overload placeholder types in the base and index // expressions. We can't handle overloads here because the other // operand might be an overloadable type, in which case the overload // resolution for the operator overload should get the first crack // at the overload. + bool IsMSPropertySubscript = false; if (base->getType()->isNonOverloadPlaceholderType()) { IsMSPropertySubscript = isMSPropertySubscriptExpr(*this, base); if (!IsMSPropertySubscript) { @@ -4664,6 +4643,24 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, base = result.get(); } } + + // If the base is a matrix type, try to create a new MatrixSubscriptExpr. + if (base->getType()->isMatrixType()) { + if (CheckAndReportCommaError(idx)) + return ExprError(); + + return CreateBuiltinMatrixSubscriptExpr(base, idx, nullptr, rbLoc); + } + + // A comma-expression as the index is deprecated in C++2a onwards. + if (getLangOpts().CPlusPlus20 && + ((isa(idx) && cast(idx)->isCommaOp()) || + (isa(idx) && + cast(idx)->getOperator() == OO_Comma))) { + Diag(idx->getExprLoc(), diag::warn_deprecated_comma_subscript) + << SourceRange(base->getBeginLoc(), rbLoc); + } + if (idx->getType()->isNonOverloadPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(idx); if (result.isInvalid()) return ExprError(); @@ -8400,7 +8397,7 @@ static bool IsArithmeticBinaryExpr(Expr *E, BinaryOperatorKind *Opcode, Expr **RHSExprs) { // Don't strip parenthesis: we should not warn if E is in parenthesis. E = E->IgnoreImpCasts(); - E = E->IgnoreConversionOperator(); + E = E->IgnoreConversionOperatorSingleStep(); E = E->IgnoreImpCasts(); if (auto *MTE = dyn_cast(E)) { E = MTE->getSubExpr(); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 21a9ad04d5008..71341e5688fe0 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1494,17 +1494,9 @@ Sema::TryImplicitConversion(Expr *From, QualType ToType, /// converted expression. Flavor is the kind of conversion we're /// performing, used in the error message. If @p AllowExplicit, /// explicit user-defined conversions are permitted. -ExprResult -Sema::PerformImplicitConversion(Expr *From, QualType ToType, - AssignmentAction Action, bool AllowExplicit) { - ImplicitConversionSequence ICS; - return PerformImplicitConversion(From, ToType, Action, AllowExplicit, ICS); -} - -ExprResult -Sema::PerformImplicitConversion(Expr *From, QualType ToType, - AssignmentAction Action, bool AllowExplicit, - ImplicitConversionSequence& ICS) { +ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, + AssignmentAction Action, + bool AllowExplicit) { if (checkPlaceholderForOverload(*this, From)) return ExprError(); @@ -1515,13 +1507,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, if (getLangOpts().ObjC) CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType, From->getType(), From); - ICS = ::TryImplicitConversion(*this, From, ToType, - /*SuppressUserConversions=*/false, - AllowExplicit ? AllowedExplicit::All - : AllowedExplicit::None, - /*InOverloadResolution=*/false, - /*CStyle=*/false, AllowObjCWritebackConversion, - /*AllowObjCConversionOnExplicit=*/false); + ImplicitConversionSequence ICS = ::TryImplicitConversion( + *this, From, ToType, + /*SuppressUserConversions=*/false, + AllowExplicit ? AllowedExplicit::All : AllowedExplicit::None, + /*InOverloadResolution=*/false, + /*CStyle=*/false, AllowObjCWritebackConversion, + /*AllowObjCConversionOnExplicit=*/false); return PerformImplicitConversion(From, ToType, ICS, Action); } diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 8b8cf8319e93a..eaa78c7cde761 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -14,6 +14,8 @@ #include "clang/AST/QualTypeNames.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/TypeVisitor.h" #include "clang/Analysis/CallGraph.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/Builtins.h" @@ -56,7 +58,7 @@ enum KernelInvocationKind { const static std::string InitMethodName = "__init"; const static std::string FinalizeMethodName = "__finalize"; -constexpr unsigned GPUMaxKernelArgsSize = 2048; +constexpr unsigned MaxKernelArgsSize = 2048; namespace { @@ -82,8 +84,8 @@ class Util { static bool isSyclHalfType(const QualType &Ty); /// Checks whether given clang type is a full specialization of the SYCL - /// property_list class. - static bool isPropertyListType(const QualType &Ty); + /// accessor_property_list class. + static bool isAccessorPropertyListType(const QualType &Ty); /// Checks whether given clang type is a full specialization of the SYCL /// buffer_location class. @@ -580,22 +582,12 @@ class KernelBodyTransform : public TreeTransform { auto NewDecl = MappingPair.second; return DeclRefExpr::Create( SemaRef.getASTContext(), DRE->getQualifierLoc(), - DRE->getTemplateKeywordLoc(), NewDecl, false, - DeclarationNameInfo(DRE->getNameInfo().getName(), SourceLocation(), - DRE->getNameInfo().getInfo()), + DRE->getTemplateKeywordLoc(), NewDecl, false, DRE->getNameInfo(), NewDecl->getType(), DRE->getValueKind()); } return DRE; } - StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc, - MultiStmtArg Statements, - SourceLocation RBraceLoc, bool IsStmtExpr) { - // Build a new compound statement but clear the source locations. - return getSema().ActOnCompoundStmt(SourceLocation(), SourceLocation(), - Statements, IsStmtExpr); - } - private: std::pair MappingPair; Sema &SemaRef; @@ -836,9 +828,9 @@ class KernelObjVisitor { // type (which doesn't exist in cases where it is a FieldDecl in the // 'root'), and Wrapper is the current struct being unwrapped. template - void visitRecord(const CXXRecordDecl *Owner, ParentTy &Parent, - const CXXRecordDecl *Wrapper, QualType RecordTy, - HandlerTys &... Handlers) { + void visitComplexRecord(const CXXRecordDecl *Owner, ParentTy &Parent, + const CXXRecordDecl *Wrapper, QualType RecordTy, + HandlerTys &... Handlers) { (void)std::initializer_list{ (Handlers.enterStruct(Owner, Parent, RecordTy), 0)...}; VisitRecordHelper(Wrapper, Wrapper->bases(), Handlers...); @@ -847,6 +839,19 @@ class KernelObjVisitor { (Handlers.leaveStruct(Owner, Parent, RecordTy), 0)...}; } + template + void visitSimpleRecord(const CXXRecordDecl *Owner, ParentTy &Parent, + const CXXRecordDecl *Wrapper, QualType RecordTy, + HandlerTys &... Handlers) { + (void)std::initializer_list{ + (Handlers.handleNonDecompStruct(Owner, Parent, RecordTy), 0)...}; + } + + template + void visitRecord(const CXXRecordDecl *Owner, ParentTy &Parent, + const CXXRecordDecl *Wrapper, QualType RecordTy, + HandlerTys &... Handlers); + template void VisitUnion(const CXXRecordDecl *Owner, ParentTy &Parent, const CXXRecordDecl *Wrapper, HandlerTys &... Handlers); @@ -916,8 +921,15 @@ class KernelObjVisitor { HandlerTys &... Handlers); template - void visitArray(const CXXRecordDecl *Owner, FieldDecl *Field, - QualType ArrayTy, HandlerTys &... Handlers) { + void visitSimpleArray(const CXXRecordDecl *Owner, FieldDecl *Field, + QualType ArrayTy, HandlerTys &... Handlers) { + (void)std::initializer_list{ + (Handlers.handleSimpleArrayType(Field, ArrayTy), 0)...}; + } + + template + void visitComplexArray(const CXXRecordDecl *Owner, FieldDecl *Field, + QualType ArrayTy, HandlerTys &... Handlers) { // Array workflow is: // handleArrayType // enterArray @@ -948,6 +960,10 @@ class KernelObjVisitor { (Handlers.leaveArray(Field, ArrayTy, ET), 0)...}; } + template + void visitArray(const CXXRecordDecl *Owner, FieldDecl *Field, + QualType ArrayTy, HandlerTys &... Handlers); + template void visitField(const CXXRecordDecl *Owner, FieldDecl *Field, QualType FieldTy, HandlerTys &... Handlers) { @@ -1011,6 +1027,10 @@ class SyclKernelFieldHandlerBase { public: static constexpr const bool VisitUnionBody = false; static constexpr const bool VisitNthArrayElement = true; + // Opt-in based on whether we should visit inside simple containers (structs, + // arrays). All of the 'check' types should likely be true, the int-header, + // and kernel decl creation types should not. + static constexpr const bool VisitInsideSimpleContainers = true; // Mark these virtual so that we can use override in the implementer classes, // despite virtual dispatch never being used. @@ -1047,6 +1067,23 @@ class SyclKernelFieldHandlerBase { // Most handlers shouldn't be handling this, just the field checker. virtual bool handleOtherType(FieldDecl *, QualType) { return true; } + // Handle a simple struct that doesn't need to be decomposed, only called on + // handlers with VisitInsideSimpleContainers as false. Replaces + // handleStructType, enterStruct, leaveStruct, and visiting of sub-elements. + virtual bool handleNonDecompStruct(const CXXRecordDecl *, FieldDecl *, + QualType) { + return true; + } + virtual bool handleNonDecompStruct(const CXXRecordDecl *, + const CXXBaseSpecifier &, QualType) { + return true; + } + + // Instead of handleArrayType, enterArray, leaveArray, and nextElement (plus + // descending down the elements), this function gets called in the event of an + // array containing simple elements (even in the case of an MD array). + virtual bool handleSimpleArrayType(FieldDecl *, QualType) { return true; } + // The following are only used for keeping track of where we are in the base // class/field graph. Int Headers use this to calculate offset, most others // don't have a need for these. @@ -1118,6 +1155,14 @@ template struct AnyTrue { static constexpr bool Value = B || AnyTrue::Value; }; +template struct AllTrue; + +template struct AllTrue { static constexpr bool Value = B; }; + +template struct AllTrue { + static constexpr bool Value = B && AllTrue::Value; +}; + template void KernelObjVisitor::VisitUnion(const CXXRecordDecl *Owner, ParentTy &Parent, const CXXRecordDecl *Wrapper, @@ -1146,6 +1191,64 @@ void KernelObjVisitor::visitNthArrayElement(const CXXRecordDecl *Owner, .Handler...); } +template +void KernelObjVisitor::visitRecord(const CXXRecordDecl *Owner, ParentTy &Parent, + const CXXRecordDecl *Wrapper, + QualType RecordTy, + HandlerTys &... Handlers) { + if (RecordTy->getAsRecordDecl()->hasAttr()) { + // If this container requires decomposition, we have to visit it as + // 'complex', so all handlers are called in this case with the 'complex' + // case. + visitComplexRecord(Owner, Parent, Wrapper, RecordTy, Handlers...); + } else { + // "Simple" Containers are those that do NOT need to be decomposed, + // "Complex" containers are those that DO. In the case where the container + // does NOT need to be decomposed, we can call VisitSimpleRecord on the + // handlers that have opted-out of VisitInsideSimpleContainers. The 'if' + // makes sure we only do that if at least 1 has opted out. + if (!AllTrue::Value) + visitSimpleRecord( + Owner, Parent, Wrapper, RecordTy, + HandlerFilter( + Handlers) + .Handler...); + + // Even though this is a 'simple' container, some handlers (via + // VisitInsideSimpleContainers = true) need to treat it as if it needs + // decomposing, so we call VisitComplexRecord iif at least one has. + if (AnyTrue::Value) + visitComplexRecord( + Owner, Parent, Wrapper, RecordTy, + HandlerFilter( + Handlers) + .Handler...); + } +} + +template +void KernelObjVisitor::visitArray(const CXXRecordDecl *Owner, FieldDecl *Field, + QualType ArrayTy, HandlerTys &... Handlers) { + + if (Field->hasAttr()) { + visitComplexArray(Owner, Field, ArrayTy, Handlers...); + } else { + if (!AllTrue::Value) + visitSimpleArray( + Owner, Field, ArrayTy, + HandlerFilter( + Handlers) + .Handler...); + + if (AnyTrue::Value) + visitComplexArray( + Owner, Field, ArrayTy, + HandlerFilter( + Handlers) + .Handler...); + } +} + // A type to check the validity of all of the argument types. class SyclKernelFieldChecker : public SyclKernelFieldHandler { bool IsInvalid = false; @@ -1194,29 +1297,31 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler { return; } QualType PropListTy = PropList.getAsType(); - if (!Util::isPropertyListType(PropListTy)) { + if (!Util::isAccessorPropertyListType(PropListTy)) { SemaRef.Diag(Loc, diag::err_sycl_invalid_accessor_property_template_param); return; } - const auto *PropListDecl = + const auto *AccPropListDecl = cast(PropListTy->getAsRecordDecl()); - if (PropListDecl->getTemplateArgs().size() != 1) { + if (AccPropListDecl->getTemplateArgs().size() != 1) { SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_param_number) - << "property_list"; + << "accessor_property_list"; return; } - const auto TemplArg = PropListDecl->getTemplateArgs()[0]; + const auto TemplArg = AccPropListDecl->getTemplateArgs()[0]; if (TemplArg.getKind() != TemplateArgument::ArgKind::Pack) { - SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_template_param) - << /*property_list*/ 0 << /*parameter pack*/ 0; + SemaRef.Diag(Loc, + diag::err_sycl_invalid_accessor_property_list_template_param) + << /*accessor_property_list*/ 0 << /*parameter pack*/ 0; return; } for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin(); Prop != TemplArg.pack_end(); ++Prop) { if (Prop->getKind() != TemplateArgument::ArgKind::Type) { - SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_template_param) - << /*property_list pack argument*/ 1 << /*type*/ 1; + SemaRef.Diag( + Loc, diag::err_sycl_invalid_accessor_property_list_template_param) + << /*accessor_property_list pack argument*/ 1 << /*type*/ 1; return; } QualType PropTy = Prop->getAsType(); @@ -1235,13 +1340,15 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler { } const auto BufferLoc = PropDecl->getTemplateArgs()[0]; if (BufferLoc.getKind() != TemplateArgument::ArgKind::Integral) { - SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_template_param) + SemaRef.Diag(Loc, + diag::err_sycl_invalid_accessor_property_list_template_param) << /*buffer_location*/ 2 << /*non-negative integer*/ 2; return; } int LocationID = static_cast(BufferLoc.getAsIntegral().getExtValue()); if (LocationID < 0) { - SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_template_param) + SemaRef.Diag(Loc, + diag::err_sycl_invalid_accessor_property_list_template_param) << /*buffer_location*/ 2 << /*non-negative integer*/ 2; return; } @@ -1377,6 +1484,132 @@ class SyclKernelUnionChecker : public SyclKernelFieldHandler { } }; +// A type to mark whether a collection requires decomposition. +class SyclKernelDecompMarker : public SyclKernelFieldHandler { + llvm::SmallVector CollectionStack; + +public: + static constexpr const bool VisitUnionBody = false; + static constexpr const bool VisitNthArrayElement = false; + + SyclKernelDecompMarker(Sema &S) : SyclKernelFieldHandler(S) { + // In order to prevent checking this over and over, just add a dummy-base + // entry. + CollectionStack.push_back(true); + } + + bool handleSyclAccessorType(const CXXRecordDecl *, const CXXBaseSpecifier &, + QualType) final { + CollectionStack.back() = true; + return true; + } + bool handleSyclAccessorType(FieldDecl *, QualType) final { + CollectionStack.back() = true; + return true; + } + + bool handleSyclSamplerType(const CXXRecordDecl *, const CXXBaseSpecifier &, + QualType) final { + CollectionStack.back() = true; + return true; + } + bool handleSyclSamplerType(FieldDecl *, QualType) final { + CollectionStack.back() = true; + return true; + } + bool handleSyclSpecConstantType(FieldDecl *, QualType) final { + CollectionStack.back() = true; + return true; + } + bool handleSyclStreamType(const CXXRecordDecl *, const CXXBaseSpecifier &, + QualType) final { + CollectionStack.back() = true; + return true; + } + bool handleSyclStreamType(FieldDecl *, QualType) final { + CollectionStack.back() = true; + return true; + } + bool handleSyclHalfType(const CXXRecordDecl *, const CXXBaseSpecifier &, + QualType) final { + CollectionStack.back() = true; + return true; + } + bool handleSyclHalfType(FieldDecl *, QualType) final { + CollectionStack.back() = true; + return true; + } + + bool handlePointerType(FieldDecl *, QualType) final { + CollectionStack.back() = true; + return true; + } + + // Stream is always decomposed (and whether it gets decomposed is handled in + // handleSyclStreamType), but we need a CollectionStack entry to capture the + // accessors that get handled. + bool enterStream(const CXXRecordDecl *, FieldDecl *, QualType) final { + CollectionStack.push_back(false); + return true; + } + bool leaveStream(const CXXRecordDecl *, FieldDecl *, QualType Ty) final { + CollectionStack.pop_back(); + return true; + } + + bool enterStruct(const CXXRecordDecl *, FieldDecl *, QualType) final { + CollectionStack.push_back(false); + return true; + } + + bool leaveStruct(const CXXRecordDecl *, FieldDecl *, QualType Ty) final { + if (CollectionStack.pop_back_val()) { + RecordDecl *RD = Ty->getAsRecordDecl(); + if (!RD->hasAttr()) + RD->addAttr(SYCLRequiresDecompositionAttr::CreateImplicit( + SemaRef.getASTContext())); + CollectionStack.back() = true; + } + return true; + } + + bool enterStruct(const CXXRecordDecl *, const CXXBaseSpecifier &, + QualType) final { + CollectionStack.push_back(false); + return true; + } + + bool leaveStruct(const CXXRecordDecl *, const CXXBaseSpecifier &, + QualType Ty) final { + if (CollectionStack.pop_back_val()) { + RecordDecl *RD = Ty->getAsRecordDecl(); + if (!RD->hasAttr()) + RD->addAttr(SYCLRequiresDecompositionAttr::CreateImplicit( + SemaRef.getASTContext())); + CollectionStack.back() = true; + } + + return true; + } + + bool enterArray(FieldDecl *, QualType ArrayTy, QualType ElementTy) final { + CollectionStack.push_back(false); + return true; + } + + bool leaveArray(FieldDecl *FD, QualType ArrayTy, QualType ElementTy) final { + if (CollectionStack.pop_back_val()) { + // Cannot assert, since in MD arrays we'll end up marking them multiple + // times. + if (!FD->hasAttr()) + FD->addAttr(SYCLRequiresDecompositionAttr::CreateImplicit( + SemaRef.getASTContext())); + CollectionStack.back() = true; + } + return true; + } +}; + // A type to Create and own the FunctionDecl for the kernel. class SyclKernelDeclCreator : public SyclKernelFieldHandler { FunctionDecl *KernelDecl; @@ -1414,19 +1647,18 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler { } // Handle accessor properties. If any properties were found in - // the property_list - add the appropriate attributes to ParmVarDecl. + // the accessor_property_list - add the appropriate attributes to ParmVarDecl. void handleAccessorPropertyList(ParmVarDecl *Param, const CXXRecordDecl *RecordDecl, SourceLocation Loc) { const auto *AccTy = cast(RecordDecl); - // TODO: when SYCL headers' part is ready - replace this 'if' with an error if (AccTy->getTemplateArgs().size() < 6) return; const auto PropList = cast(AccTy->getTemplateArgs()[5]); QualType PropListTy = PropList.getAsType(); - const auto *PropListDecl = + const auto *AccPropListDecl = cast(PropListTy->getAsRecordDecl()); - const auto TemplArg = PropListDecl->getTemplateArgs()[0]; + const auto TemplArg = AccPropListDecl->getTemplateArgs()[0]; // Move through TemplateArgs list of a property list and search for // properties. If found - apply the appropriate attribute to ParmVarDecl. for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin(); @@ -1512,6 +1744,7 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler { } public: + static constexpr const bool VisitInsideSimpleContainers = false; SyclKernelDeclCreator(Sema &S, StringRef Name, SourceLocation Loc, bool IsInline, bool IsSIMDKernel) : SyclKernelFieldHandler(S), @@ -1553,6 +1786,18 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler { return true; } + bool enterStruct(const CXXRecordDecl *, const CXXBaseSpecifier &BS, + QualType FieldTy) final { + ++StructDepth; + return true; + } + + bool leaveStruct(const CXXRecordDecl *, const CXXBaseSpecifier &BS, + QualType FieldTy) final { + --StructDepth; + return true; + } + bool handleSyclAccessorType(const CXXRecordDecl *, const CXXBaseSpecifier &BS, QualType FieldTy) final { const auto *RecordDecl = FieldTy->getAsCXXRecordDecl(); @@ -1627,11 +1872,32 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler { return true; } + bool handleSimpleArrayType(FieldDecl *FD, QualType FieldTy) final { + // Arrays are always wrapped in a struct since they cannot be passed + // directly. + RecordDecl *WrappedArray = wrapField(FD, FieldTy); + QualType ModTy = SemaRef.getASTContext().getRecordType(WrappedArray); + addParam(FD, ModTy); + return true; + } + bool handleScalarType(FieldDecl *FD, QualType FieldTy) final { addParam(FD, FieldTy); return true; } + bool handleNonDecompStruct(const CXXRecordDecl *, FieldDecl *FD, + QualType Ty) final { + addParam(FD, Ty); + return true; + } + + bool handleNonDecompStruct(const CXXRecordDecl *Base, + const CXXBaseSpecifier &BS, QualType Ty) final { + addParam(BS, Ty); + return true; + } + bool handleUnionType(FieldDecl *FD, QualType FieldTy) final { return handleScalarType(FD, FieldTy); } @@ -1663,9 +1929,6 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler { } using SyclKernelFieldHandler::handleSyclHalfType; using SyclKernelFieldHandler::handleSyclSamplerType; - // Required to handle pointers inside structs - using SyclKernelFieldHandler::enterStruct; - using SyclKernelFieldHandler::leaveStruct; }; class SyclKernelArgsSizeChecker : public SyclKernelFieldHandler { @@ -1688,15 +1951,14 @@ class SyclKernelArgsSizeChecker : public SyclKernelFieldHandler { } public: + static constexpr const bool VisitInsideSimpleContainers = false; SyclKernelArgsSizeChecker(Sema &S, SourceLocation Loc) : SyclKernelFieldHandler(S), KernelLoc(Loc) {} ~SyclKernelArgsSizeChecker() { - if (SemaRef.Context.getTargetInfo().getTriple().getSubArch() == - llvm::Triple::SPIRSubArch_gen) - if (SizeOfParams > GPUMaxKernelArgsSize) - SemaRef.Diag(KernelLoc, diag::warn_sycl_kernel_too_big_args) - << SizeOfParams << GPUMaxKernelArgsSize; + if (SizeOfParams > MaxKernelArgsSize) + SemaRef.Diag(KernelLoc, diag::warn_sycl_kernel_too_big_args) + << SizeOfParams << MaxKernelArgsSize; } bool handleSyclAccessorType(FieldDecl *FD, QualType FieldTy) final { @@ -1727,6 +1989,23 @@ class SyclKernelArgsSizeChecker : public SyclKernelFieldHandler { return true; } + bool handleSimpleArrayType(FieldDecl *FD, QualType FieldTy) final { + addParam(FieldTy); + return true; + } + + bool handleNonDecompStruct(const CXXRecordDecl *, FieldDecl *FD, + QualType Ty) final { + addParam(Ty); + return true; + } + + bool handleNonDecompStruct(const CXXRecordDecl *Base, + const CXXBaseSpecifier &BS, QualType Ty) final { + addParam(Ty); + return true; + } + bool handleUnionType(FieldDecl *FD, QualType FieldTy) final { return handleScalarType(FD, FieldTy); } @@ -1872,6 +2151,19 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler { return DRE; } + Expr *createSimpleArrayParamReferenceExpr(QualType ArrayTy) { + ParmVarDecl *KernelParameter = + DeclCreator.getParamVarDeclsForCurrentField()[0]; + QualType ParamType = KernelParameter->getOriginalType(); + Expr *DRE = SemaRef.BuildDeclRefExpr(KernelParameter, ParamType, VK_LValue, + KernelCallerSrcLoc); + + // Unwrap the array. + CXXRecordDecl *WrapperStruct = ParamType->getAsCXXRecordDecl(); + FieldDecl *ArrayField = *(WrapperStruct->field_begin()); + return buildMemberExpr(DRE, ArrayField); + } + // Returns 'true' if the thing we're visiting (Based on the FD/QualType pair) // is an element of an array. This will determine whether we do // MemberExprBases in some cases or not, AND determines how we initialize @@ -1899,8 +2191,11 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler { void addFieldInit(FieldDecl *FD, QualType Ty, MultiExprArg ParamRef, InitializationKind InitKind) { - InitializedEntity Entity = getFieldEntity(FD, Ty); + addFieldInit(FD, Ty, ParamRef, InitKind, getFieldEntity(FD, Ty)); + } + void addFieldInit(FieldDecl *FD, QualType Ty, MultiExprArg ParamRef, + InitializationKind InitKind, InitializedEntity Entity) { InitializationSequence InitSeq(SemaRef, Entity, InitKind, ParamRef); ExprResult Init = InitSeq.Perform(SemaRef, Entity, InitKind, ParamRef); @@ -1921,6 +2216,22 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler { Init.get()); } + void addSimpleBaseInit(const CXXBaseSpecifier &BS, QualType Ty) { + InitializationKind InitKind = + InitializationKind::CreateCopy(KernelCallerSrcLoc, KernelCallerSrcLoc); + + InitializedEntity Entity = InitializedEntity::InitializeBase( + SemaRef.Context, &BS, /*IsInheritedVirtualBase*/ false, &VarEntity); + + Expr *ParamRef = createParamReferenceExpr(); + InitializationSequence InitSeq(SemaRef, Entity, InitKind, ParamRef); + ExprResult Init = InitSeq.Perform(SemaRef, Entity, InitKind, ParamRef); + + InitListExpr *ParentILE = CollectionInitExprs.back(); + ParentILE->updateInit(SemaRef.getASTContext(), ParentILE->getNumInits(), + Init.get()); + } + // Adds an initializer that handles a simple initialization of a field. void addSimpleFieldInit(FieldDecl *FD, QualType Ty) { Expr *ParamRef = createParamReferenceExpr(); @@ -2054,6 +2365,7 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler { } public: + static constexpr const bool VisitInsideSimpleContainers = false; SyclKernelBodyCreator(Sema &S, SyclKernelDeclCreator &DC, const CXXRecordDecl *KernelObj, FunctionDecl *KernelCallerFunc) @@ -2123,6 +2435,29 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler { return true; } + bool handleSimpleArrayType(FieldDecl *FD, QualType FieldTy) final { + Expr *ArrayRef = createSimpleArrayParamReferenceExpr(FieldTy); + InitializationKind InitKind = InitializationKind::CreateDirect({}, {}, {}); + + InitializedEntity Entity = + InitializedEntity::InitializeMember(FD, &VarEntity, /*Implicit*/ true); + + addFieldInit(FD, FieldTy, ArrayRef, InitKind, Entity); + return true; + } + + bool handleNonDecompStruct(const CXXRecordDecl *, FieldDecl *FD, + QualType Ty) final { + addSimpleFieldInit(FD, Ty); + return true; + } + + bool handleNonDecompStruct(const CXXRecordDecl *Base, + const CXXBaseSpecifier &BS, QualType Ty) final { + addSimpleBaseInit(BS, Ty); + return true; + } + bool handleScalarType(FieldDecl *FD, QualType FieldTy) final { addSimpleFieldInit(FD, FieldTy); return true; @@ -2283,10 +2618,9 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler { void addParam(const FieldDecl *FD, QualType ArgTy, SYCLIntegrationHeader::kernel_param_kind_t Kind) { - addParam(FD, ArgTy, Kind, offsetOf(FD, ArgTy)); + addParam(ArgTy, Kind, offsetOf(FD, ArgTy)); } - void addParam(const FieldDecl *FD, QualType ArgTy, - SYCLIntegrationHeader::kernel_param_kind_t Kind, + void addParam(QualType ArgTy, SYCLIntegrationHeader::kernel_param_kind_t Kind, uint64_t OffsetAdj) { uint64_t Size; Size = SemaRef.getASTContext().getTypeSizeInChars(ArgTy).getQuantity(); @@ -2303,6 +2637,7 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler { } public: + static constexpr const bool VisitInsideSimpleContainers = false; SyclKernelIntHeaderCreator(Sema &S, SYCLIntegrationHeader &H, const CXXRecordDecl *KernelObj, QualType NameType, StringRef Name, StringRef StableName) @@ -2355,7 +2690,7 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler { // offsetOf calculation wouldn't work correctly. Therefore, we need to call // a version of addParam where we calculate the offset based on the true // FieldDecl/FieldType pair, rather than the SampleArg type. - addParam(FD, SamplerArg->getType(), SYCLIntegrationHeader::kind_sampler, + addParam(SamplerArg->getType(), SYCLIntegrationHeader::kind_sampler, offsetOf(FD, FieldTy)); return true; } @@ -2388,6 +2723,26 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler { return true; } + bool handleSimpleArrayType(FieldDecl *FD, QualType FieldTy) final { + // Arrays are always wrapped inside of structs, so just treat it as a simple + // struct. + addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout); + return true; + } + + bool handleNonDecompStruct(const CXXRecordDecl *, FieldDecl *FD, + QualType Ty) final { + addParam(FD, Ty, SYCLIntegrationHeader::kind_std_layout); + return true; + } + + bool handleNonDecompStruct(const CXXRecordDecl *Base, + const CXXBaseSpecifier &, QualType Ty) final { + addParam(Ty, SYCLIntegrationHeader::kind_std_layout, + offsetOf(Base, Ty->getAsCXXRecordDecl())); + return true; + } + bool handleUnionType(FieldDecl *FD, QualType FieldTy) final { return handleScalarType(FD, FieldTy); } @@ -2470,9 +2825,111 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler { } // namespace +class SYCLKernelNameTypeVisitor + : public TypeVisitor, + public ConstTemplateArgumentVisitor { + Sema &S; + SourceLocation KernelInvocationFuncLoc; + using InnerTypeVisitor = TypeVisitor; + using InnerTAVisitor = + ConstTemplateArgumentVisitor; + +public: + SYCLKernelNameTypeVisitor(Sema &S, SourceLocation KernelInvocationFuncLoc) + : S(S), KernelInvocationFuncLoc(KernelInvocationFuncLoc) {} + + void Visit(QualType T) { + if (T.isNull()) + return; + const CXXRecordDecl *RD = T->getAsCXXRecordDecl(); + if (!RD) + return; + // If KernelNameType has template args visit each template arg via + // ConstTemplateArgumentVisitor + if (const auto *TSD = dyn_cast(RD)) { + const TemplateArgumentList &Args = TSD->getTemplateArgs(); + for (unsigned I = 0; I < Args.size(); I++) { + Visit(Args[I]); + } + } else { + InnerTypeVisitor::Visit(T.getTypePtr()); + } + } + + void Visit(const TemplateArgument &TA) { + if (TA.isNull()) + return; + InnerTAVisitor::Visit(TA); + } + + void VisitEnumType(const EnumType *T) { + const EnumDecl *ED = T->getDecl(); + if (!ED->isScoped() && !ED->isFixed()) { + S.Diag(KernelInvocationFuncLoc, diag::err_sycl_kernel_incorrectly_named) + << /* Unscoped enum requires fixed underlying type */ 2; + S.Diag(ED->getSourceRange().getBegin(), diag::note_entity_declared_at) + << ED; + } + } + + void VisitRecordType(const RecordType *T) { + return VisitTagDecl(T->getDecl()); + } + + void VisitTagDecl(const TagDecl *Tag) { + bool UnnamedLambdaEnabled = + S.getASTContext().getLangOpts().SYCLUnnamedLambda; + if (!Tag->getDeclContext()->isTranslationUnit() && + !isa(Tag->getDeclContext()) && !UnnamedLambdaEnabled) { + const bool KernelNameIsMissing = Tag->getName().empty(); + if (KernelNameIsMissing) { + S.Diag(KernelInvocationFuncLoc, diag::err_sycl_kernel_incorrectly_named) + << /* kernel name is missing */ 0; + } else { + if (Tag->isCompleteDefinition()) + S.Diag(KernelInvocationFuncLoc, + diag::err_sycl_kernel_incorrectly_named) + << /* kernel name is not globally-visible */ 1; + else + S.Diag(KernelInvocationFuncLoc, diag::warn_sycl_implicit_decl); + + S.Diag(Tag->getSourceRange().getBegin(), diag::note_previous_decl) + << Tag->getName(); + } + } + } + + void VisitTypeTemplateArgument(const TemplateArgument &TA) { + QualType T = TA.getAsType(); + if (const auto *ET = T->getAs()) + VisitEnumType(ET); + else + Visit(T); + } + + void VisitIntegralTemplateArgument(const TemplateArgument &TA) { + QualType T = TA.getIntegralType(); + if (const EnumType *ET = T->getAs()) + VisitEnumType(ET); + } + + void VisitTemplateTemplateArgument(const TemplateArgument &TA) { + TemplateDecl *TD = TA.getAsTemplate().getAsTemplateDecl(); + TemplateParameterList *TemplateParams = TD->getTemplateParameters(); + for (NamedDecl *P : *TemplateParams) { + if (NonTypeTemplateParmDecl *TemplateParam = + dyn_cast(P)) + if (const EnumType *ET = TemplateParam->getType()->getAs()) + VisitEnumType(ET); + } + } +}; + void Sema::CheckSYCLKernelCall(FunctionDecl *KernelFunc, SourceRange CallLoc, ArrayRef Args) { const CXXRecordDecl *KernelObj = getKernelObjectType(KernelFunc); + QualType KernelNameType = + calculateKernelNameType(getASTContext(), KernelFunc); if (!KernelObj) { Diag(Args[0]->getExprLoc(), diag::err_sycl_kernel_not_function_object); KernelFunc->setInvalidDecl(); @@ -2488,9 +2945,6 @@ void Sema::CheckSYCLKernelCall(FunctionDecl *KernelFunc, SourceRange CallLoc, } } - SyclKernelFieldChecker FieldChecker(*this); - SyclKernelUnionChecker UnionChecker(*this); - SyclKernelArgsSizeChecker ArgsSizeChecker(*this, Args[0]->getExprLoc()); // check that calling kernel conforms to spec QualType KernelParamTy = KernelFunc->getParamDecl(0)->getType(); if (KernelParamTy->isReferenceType()) { @@ -2507,12 +2961,28 @@ void Sema::CheckSYCLKernelCall(FunctionDecl *KernelFunc, SourceRange CallLoc, if (KernelObj->isInvalidDecl()) return; + SyclKernelDecompMarker DecompMarker(*this); + SyclKernelFieldChecker FieldChecker(*this); + SyclKernelUnionChecker UnionChecker(*this); + SyclKernelArgsSizeChecker ArgsSizeChecker(*this, Args[0]->getExprLoc()); + KernelObjVisitor Visitor{*this}; + SYCLKernelNameTypeVisitor KernelTypeVisitor(*this, Args[0]->getExprLoc()); + // Emit diagnostics for SYCL device kernels only + if (LangOpts.SYCLIsDevice) + KernelTypeVisitor.Visit(KernelNameType); DiagnosingSYCLKernel = true; - Visitor.VisitRecordBases(KernelObj, FieldChecker, UnionChecker, - ArgsSizeChecker); + Visitor.VisitRecordBases(KernelObj, FieldChecker, UnionChecker, DecompMarker); Visitor.VisitRecordFields(KernelObj, FieldChecker, UnionChecker, - ArgsSizeChecker); + DecompMarker); + // ArgSizeChecker needs to happen after DecompMarker has completed, since it + // cares about the decomp attributes. DecompMarker cannot run before the + // others, since it counts on the FieldChecker to make sure it is visiting + // valid arrays/etc. Thus, ArgSizeChecker has its own visitation. + if (FieldChecker.isValid() && UnionChecker.isValid()) { + Visitor.VisitRecordBases(KernelObj, ArgsSizeChecker); + Visitor.VisitRecordFields(KernelObj, ArgsSizeChecker); + } DiagnosingSYCLKernel = false; if (!FieldChecker.isValid() || !UnionChecker.isValid()) KernelFunc->setInvalidDecl(); @@ -2629,15 +3099,15 @@ void Sema::MarkDevice(void) { KernelBody ? KernelBody->getAttr() : nullptr; if (auto *Existing = SYCLKernel->getAttr()) { - if (getIntExprValue(Existing->getSubGroupSize(), getASTContext()) != - getIntExprValue(Attr->getSubGroupSize(), getASTContext())) { + if (getIntExprValue(Existing->getValue(), getASTContext()) != + getIntExprValue(Attr->getValue(), getASTContext())) { Diag(SYCLKernel->getLocation(), diag::err_conflicting_sycl_kernel_attributes); Diag(Existing->getLocation(), diag::note_conflicting_attribute); Diag(Attr->getLocation(), diag::note_conflicting_attribute); SYCLKernel->setInvalidDecl(); } - } else if (KBSimdAttr && (getIntExprValue(Attr->getSubGroupSize(), + } else if (KBSimdAttr && (getIntExprValue(Attr->getValue(), getASTContext()) != 1)) { reportConflictingAttrs(*this, KernelBody, KBSimdAttr, Attr); } else { @@ -2853,18 +3323,6 @@ static void emitWithoutAnonNamespaces(llvm::raw_ostream &OS, StringRef Source) { OS << Source; } -static bool checkEnumTemplateParameter(const EnumDecl *ED, - DiagnosticsEngine &Diag, - SourceLocation KernelLocation) { - if (!ED->isScoped() && !ED->isFixed()) { - Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named) << 2; - Diag.Report(ED->getSourceRange().getBegin(), diag::note_entity_declared_at) - << ED; - return true; - } - return false; -} - // Emits a forward declaration void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D, SourceLocation KernelLocation) { @@ -2877,34 +3335,15 @@ void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D, auto *NS = dyn_cast_or_null(DC); if (!NS) { - if (!DC->isTranslationUnit()) { - const TagDecl *TD = isa(D) - ? cast(D)->getTemplatedDecl() - : dyn_cast(D); - - if (TD && !UnnamedLambdaSupport) { - // defined class constituting the kernel name is not globally - // accessible - contradicts the spec - const bool KernelNameIsMissing = TD->getName().empty(); - if (KernelNameIsMissing) { - Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named) - << /* kernel name is missing */ 0; - // Don't emit note if kernel name was completely omitted - } else { - if (TD->isCompleteDefinition()) - Diag.Report(KernelLocation, - diag::err_sycl_kernel_incorrectly_named) - << /* kernel name is not globally-visible */ 1; - else - Diag.Report(KernelLocation, diag::warn_sycl_implicit_decl); - Diag.Report(D->getSourceRange().getBegin(), - diag::note_previous_decl) - << TD->getName(); - } - } - } break; } + + if (NS->isStdNamespace()) { + Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named) + << /* name cannot be a type in the std namespace */ 3; + return; + } + ++NamespaceCnt; const StringRef NSInlinePrefix = NS->isInline() ? "inline " : ""; NSStr.insert( @@ -2987,8 +3426,13 @@ void SYCLIntegrationHeader::emitForwardClassDecls( ; const CXXRecordDecl *RD = T->getAsCXXRecordDecl(); - if (!RD) + if (!RD) { + if (T->isNullPtrType()) + Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named) + << /* name cannot be a type in the std namespace */ 3; + return; + } // see if this is a template specialization ... if (const auto *TSD = dyn_cast(RD)) { @@ -3010,7 +3454,6 @@ void SYCLIntegrationHeader::emitForwardClassDecls( // Handle Kernel Name Type templated using enum type and value. if (const auto *ET = T->getAs()) { const EnumDecl *ED = ET->getDecl(); - if (!checkEnumTemplateParameter(ED, Diag, KernelLocation)) emitFwdDecl(O, ED, KernelLocation); } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) emitForwardClassDecls(O, T, KernelLocation, Printed); @@ -3070,7 +3513,6 @@ void SYCLIntegrationHeader::emitForwardClassDecls( QualType T = TemplateParam->getType(); if (const auto *ET = T->getAs()) { const EnumDecl *ED = ET->getDecl(); - if (!checkEnumTemplateParameter(ED, Diag, KernelLocation)) emitFwdDecl(O, ED, KernelLocation); } } @@ -3305,30 +3747,8 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) { } O << "};\n\n"; - O << "// indices into the kernel_signatures array, each representing a " - "start" - " of\n"; - O << "// kernel signature descriptor subarray of the kernel_signatures" - " array;\n"; - O << "// the index order in this array corresponds to the kernel name order" - " in the\n"; - O << "// kernel_names array\n"; - O << "static constexpr\n"; - O << "const unsigned kernel_signature_start[] = {\n"; - unsigned CurStart = 0; - - for (unsigned I = 0; I < KernelDescs.size(); I++) { - auto &K = KernelDescs[I]; - O << " " << CurStart; - if (I < KernelDescs.size() - 1) - O << ","; - O << " // " << K.Name << "\n"; - CurStart += K.Params.size() + 1; - } - O << "};\n\n"; - O << "// Specializations of KernelInfo for kernel function types:\n"; - CurStart = 0; + unsigned CurStart = 0; for (const KernelDesc &K : KernelDescs) { const size_t N = K.Params.size(); @@ -3455,20 +3875,17 @@ bool Util::isSyclSpecConstantType(const QualType &Ty) { return matchQualifiedTypeName(Ty, Scopes); } -bool Util::isPropertyListType(const QualType &Ty) { - return isSyclType(Ty, "property_list", true /*Tmpl*/); -} - bool Util::isSyclBufferLocationType(const QualType &Ty) { - const StringRef &Name = "buffer_location"; - std::array Scopes = { - Util::DeclContextDesc{clang::Decl::Kind::Namespace, "cl"}, - Util::DeclContextDesc{clang::Decl::Kind::Namespace, "sycl"}, - // TODO: this doesn't belong to property namespace, instead it shall be - // in its own namespace. Change it, when the actual implementation in SYCL - // headers is ready - Util::DeclContextDesc{clang::Decl::Kind::Namespace, "property"}, - Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization, Name}}; + const StringRef &PropertyName = "buffer_location"; + const StringRef &InstanceName = "instance"; + std::array Scopes = { + Util::DeclContextDesc{Decl::Kind::Namespace, "cl"}, + Util::DeclContextDesc{Decl::Kind::Namespace, "sycl"}, + Util::DeclContextDesc{Decl::Kind::Namespace, "INTEL"}, + Util::DeclContextDesc{Decl::Kind::Namespace, "property"}, + Util::DeclContextDesc{Decl::Kind::CXXRecord, PropertyName}, + Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization, + InstanceName}}; return matchQualifiedTypeName(Ty, Scopes); } @@ -3482,6 +3899,16 @@ bool Util::isSyclType(const QualType &Ty, StringRef Name, bool Tmpl) { return matchQualifiedTypeName(Ty, Scopes); } +bool Util::isAccessorPropertyListType(const QualType &Ty) { + const StringRef &Name = "accessor_property_list"; + std::array Scopes = { + Util::DeclContextDesc{clang::Decl::Kind::Namespace, "cl"}, + Util::DeclContextDesc{clang::Decl::Kind::Namespace, "sycl"}, + Util::DeclContextDesc{clang::Decl::Kind::Namespace, "ONEAPI"}, + Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization, Name}}; + return matchQualifiedTypeName(Ty, Scopes); +} + bool Util::matchQualifiedTypeName(const QualType &Ty, ArrayRef Scopes) { // The idea: check the declaration context chain starting from the type diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index a9526671fd5a3..fd1b49cb4dc0d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -541,15 +541,16 @@ static void instantiateSYCLIntelPipeIOAttr( S.addSYCLIntelPipeIOAttr(New, *Attr, Result.getAs()); } -static void instantiateIntelReqdSubGroupSizeAttr( +template +static void instantiateIntelSYCLFunctionAttr( Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, - const IntelReqdSubGroupSizeAttr *Attr, Decl *New) { - // The SubGroupSize expression is a constant expression. + const AttrName *Attr, Decl *New) { EnterExpressionEvaluationContext Unevaluated( S, Sema::ExpressionEvaluationContext::ConstantEvaluated); - ExprResult Result = S.SubstExpr(Attr->getSubGroupSize(), TemplateArgs); + ExprResult Result = S.SubstExpr(Attr->getValue(), TemplateArgs); if (!Result.isInvalid()) - S.addIntelReqdSubGroupSizeAttr(New, *Attr, Result.getAs()); + S.addIntelSYCLSingleArgFunctionAttr(New, *Attr, + Result.getAs()); } void Sema::InstantiateAttrsForDecl( @@ -697,8 +698,14 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, } if (const auto *IntelReqdSubGroupSize = dyn_cast(TmplAttr)) { - instantiateIntelReqdSubGroupSizeAttr(*this, TemplateArgs, - IntelReqdSubGroupSize, New); + instantiateIntelSYCLFunctionAttr( + *this, TemplateArgs, IntelReqdSubGroupSize, New); + continue; + } + if (const auto *SYCLIntelNumSimdWorkItems = + dyn_cast(TmplAttr)) { + instantiateIntelSYCLFunctionAttr( + *this, TemplateArgs, SYCLIntelNumSimdWorkItems, New); continue; } // Existing DLL attribute on the instantiation takes precedence. diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 9d95fa9b447ee..88073dfc39298 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3722,7 +3722,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } case LATE_PARSED_TEMPLATE: - LateParsedTemplates.append(Record.begin(), Record.end()); + LateParsedTemplates.emplace_back( + std::piecewise_construct, std::forward_as_tuple(&F), + std::forward_as_tuple(Record.begin(), Record.end())); break; case OPTIMIZE_PRAGMA_OPTIONS: @@ -8396,25 +8398,28 @@ void ASTReader::ReadPendingInstantiations( void ASTReader::ReadLateParsedTemplates( llvm::MapVector> &LPTMap) { - for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N; - /* In loop */) { - FunctionDecl *FD = cast(GetDecl(LateParsedTemplates[Idx++])); + for (auto &LPT : LateParsedTemplates) { + ModuleFile *FMod = LPT.first; + RecordDataImpl &LateParsed = LPT.second; + for (unsigned Idx = 0, N = LateParsed.size(); Idx < N; + /* In loop */) { + FunctionDecl *FD = + cast(GetLocalDecl(*FMod, LateParsed[Idx++])); - auto LT = std::make_unique(); - LT->D = GetDecl(LateParsedTemplates[Idx++]); + auto LT = std::make_unique(); + LT->D = GetLocalDecl(*FMod, LateParsed[Idx++]); - ModuleFile *F = getOwningModuleFile(LT->D); - assert(F && "No module"); + ModuleFile *F = getOwningModuleFile(LT->D); + assert(F && "No module"); - unsigned TokN = LateParsedTemplates[Idx++]; - LT->Toks.reserve(TokN); - for (unsigned T = 0; T < TokN; ++T) - LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx)); + unsigned TokN = LateParsed[Idx++]; + LT->Toks.reserve(TokN); + for (unsigned T = 0; T < TokN; ++T) + LT->Toks.push_back(ReadToken(*F, LateParsed, Idx)); - LPTMap.insert(std::make_pair(FD, std::move(LT))); + LPTMap.insert(std::make_pair(FD, std::move(LT))); + } } - - LateParsedTemplates.clear(); } void ASTReader::LoadSelector(Selector Sel) { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 47b378f5727b4..f5a66dc3c2d10 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -585,7 +585,7 @@ void ASTDeclReader::VisitDecl(Decl *D) { Reader.getContext()); } D->setLocation(ThisDeclLoc); - D->setInvalidDecl(Record.readInt()); + D->InvalidDecl = Record.readInt(); if (Record.readInt()) { // hasAttrs AttrVec Attrs; Record.readAttributes(Attrs); diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index a42ed2f3c179d..542e75e77c3a5 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -132,15 +132,38 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, return Missing; } + // The ModuleManager's use of FileEntry nodes as the keys for its map of + // loaded modules is less than ideal. Uniqueness for FileEntry nodes is + // maintained by FileManager, which in turn uses inode numbers on hosts + // that support that. When coupled with the module cache's proclivity for + // turning over and deleting stale PCMs, this means entries for different + // module files can wind up reusing the same underlying inode. When this + // happens, subsequent accesses to the Modules map will disagree on the + // ModuleFile associated with a given file. In general, it is not sufficient + // to resolve this conundrum with a type like FileEntryRef that stores the + // name of the FileEntry node on first access because of path canonicalization + // issues. However, the paths constructed for implicit module builds are + // fully under Clang's control. We *can*, therefore, rely on their structure + // being consistent across operating systems and across subsequent accesses + // to the Modules map. + auto implicitModuleNamesMatch = [](ModuleKind Kind, const ModuleFile *MF, + const FileEntry *Entry) -> bool { + if (Kind != MK_ImplicitModule) + return true; + return Entry->getName() == MF->FileName; + }; + // Check whether we already loaded this module, before if (ModuleFile *ModuleEntry = Modules.lookup(Entry)) { - // Check the stored signature. - if (checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr)) - return OutOfDate; - - Module = ModuleEntry; - updateModuleImports(*ModuleEntry, ImportedBy, ImportLoc); - return AlreadyLoaded; + if (implicitModuleNamesMatch(Type, ModuleEntry, Entry)) { + // Check the stored signature. + if (checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr)) + return OutOfDate; + + Module = ModuleEntry; + updateModuleImports(*ModuleEntry, ImportedBy, ImportLoc); + return AlreadyLoaded; + } } // Allocate a new module. diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index c65d58e49d785..b71c19a80da90 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -249,15 +249,21 @@ class StdLibraryFunctionsChecker } }; - // Represents a buffer argument with an additional size argument. - // E.g. the first two arguments here: + // Represents a buffer argument with an additional size constraint. The + // constraint may be a concrete value, or a symbolic value in an argument. + // Example 1. Concrete value as the minimum buffer size. + // char *asctime_r(const struct tm *restrict tm, char *restrict buf); + // // `buf` size must be at least 26 bytes according the POSIX standard. + // Example 2. Argument as a buffer size. // ctime_s(char *buffer, rsize_t bufsz, const time_t *time); - // Another example: + // Example 3. The size is computed as a multiplication of other args. // size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); // // Here, ptr is the buffer, and its minimum size is `size * nmemb`. class BufferSizeConstraint : public ValueConstraint { + // The concrete value which is the minimum size for the buffer. + llvm::Optional ConcreteSize; // The argument which holds the size of the buffer. - ArgNo SizeArgN; + llvm::Optional SizeArgN; // The argument which is a multiplier to size. This is set in case of // `fread` like functions where the size is computed as a multiplication of // two arguments. @@ -266,9 +272,10 @@ class StdLibraryFunctionsChecker BinaryOperator::Opcode Op = BO_LE; public: + BufferSizeConstraint(ArgNo Buffer, llvm::APSInt BufMinSize) + : ValueConstraint(Buffer), ConcreteSize(BufMinSize) {} BufferSizeConstraint(ArgNo Buffer, ArgNo BufSize) : ValueConstraint(Buffer), SizeArgN(BufSize) {} - BufferSizeConstraint(ArgNo Buffer, ArgNo BufSize, ArgNo BufSizeMultiplier) : ValueConstraint(Buffer), SizeArgN(BufSize), SizeMultiplierArgN(BufSizeMultiplier) {} @@ -279,14 +286,27 @@ class StdLibraryFunctionsChecker SValBuilder &SvalBuilder = C.getSValBuilder(); // The buffer argument. SVal BufV = getArgSVal(Call, getArgNo()); - // The size argument. - SVal SizeV = getArgSVal(Call, SizeArgN); - // Multiply with another argument if given. - if (SizeMultiplierArgN) { - SVal SizeMulV = getArgSVal(Call, *SizeMultiplierArgN); - SizeV = SvalBuilder.evalBinOp(State, BO_Mul, SizeV, SizeMulV, - Summary.getArgType(SizeArgN)); - } + + // Get the size constraint. + const SVal SizeV = [this, &State, &Call, &Summary, &SvalBuilder]() { + if (ConcreteSize) { + return SVal(SvalBuilder.makeIntVal(*ConcreteSize)); + } else if (SizeArgN) { + // The size argument. + SVal SizeV = getArgSVal(Call, *SizeArgN); + // Multiply with another argument if given. + if (SizeMultiplierArgN) { + SVal SizeMulV = getArgSVal(Call, *SizeMultiplierArgN); + SizeV = SvalBuilder.evalBinOp(State, BO_Mul, SizeV, SizeMulV, + Summary.getArgType(*SizeArgN)); + } + return SizeV; + } else { + llvm_unreachable("The constraint must be either a concrete value or " + "encoded in an arguement."); + } + }(); + // The dynamic size of the buffer argument, got from the analyzer engine. SVal BufDynSize = getDynamicSizeWithOffset(State, BufV); @@ -744,21 +764,38 @@ bool StdLibraryFunctionsChecker::evalCall(const CallEvent &Call, bool StdLibraryFunctionsChecker::Signature::matches( const FunctionDecl *FD) const { assert(!isInvalid()); - // Check number of arguments: + // Check the number of arguments. if (FD->param_size() != ArgTys.size()) return false; - // Check return type. - if (!isIrrelevant(RetTy)) - if (RetTy != FD->getReturnType().getCanonicalType()) + // The "restrict" keyword is illegal in C++, however, many libc + // implementations use the "__restrict" compiler intrinsic in functions + // prototypes. The "__restrict" keyword qualifies a type as a restricted type + // even in C++. + // In case of any non-C99 languages, we don't want to match based on the + // restrict qualifier because we cannot know if the given libc implementation + // qualifies the paramter type or not. + auto RemoveRestrict = [&FD](QualType T) { + if (!FD->getASTContext().getLangOpts().C99) + T.removeLocalRestrict(); + return T; + }; + + // Check the return type. + if (!isIrrelevant(RetTy)) { + QualType FDRetTy = RemoveRestrict(FD->getReturnType().getCanonicalType()); + if (RetTy != FDRetTy) return false; + } - // Check argument types. + // Check the argument types. for (size_t I = 0, E = ArgTys.size(); I != E; ++I) { QualType ArgTy = ArgTys[I]; if (isIrrelevant(ArgTy)) continue; - if (ArgTy != FD->getParamDecl(I)->getType().getCanonicalType()) + QualType FDArgTy = + RemoveRestrict(FD->getParamDecl(I)->getType().getCanonicalType()); + if (ArgTy != FDArgTy) return false; } @@ -914,6 +951,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( const QualType ConstWchar_tPtrTy = getPointerTy(getConstTy(WCharTy)); // const wchar_t * const QualType ConstVoidPtrRestrictTy = getRestrictTy(ConstVoidPtrTy); + const QualType SizePtrTy = getPointerTy(SizeTy); + const QualType SizePtrRestrictTy = getRestrictTy(SizePtrTy); const RangeInt IntMax = BVF.getMaxValue(IntTy).getLimitedValue(); const RangeInt UnsignedIntMax = @@ -989,6 +1028,12 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( for (const Summary &S : Summaries) operator()(Name, S); } + // Add the same summary for different names with the Signature explicitly + // given. + void operator()(std::vector Names, Signature Sign, Summary Sum) { + for (StringRef Name : Names) + operator()(Name, Sign, Sum); + } } addToFunctionSummaryMap(ACtx, FunctionSummaryMap, DisplayLoadedSummaries); // Below are helpers functions to create the summaries. @@ -2013,6 +2058,225 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( BufferSize(/*Buffer=*/ArgNo(4), /*BufSize=*/ArgNo(5))) .ArgConstraint( ArgumentCondition(5, WithinRange, Range(0, Socklen_tMax)))); + + Optional StructUtimbufTy = lookupTy("utimbuf"); + Optional StructUtimbufPtrTy = getPointerTy(StructUtimbufTy); + + // int utime(const char *filename, struct utimbuf *buf); + addToFunctionSummaryMap( + "utime", Summary(ArgTypes{ConstCharPtrTy, StructUtimbufPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + Optional StructTimespecTy = lookupTy("timespec"); + Optional StructTimespecPtrTy = getPointerTy(StructTimespecTy); + Optional ConstStructTimespecPtrTy = + getPointerTy(getConstTy(StructTimespecTy)); + + // int futimens(int fd, const struct timespec times[2]); + addToFunctionSummaryMap( + "futimens", Summary(ArgTypes{IntTy, ConstStructTimespecPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, + Range(0, IntMax)))); + + // int utimensat(int dirfd, const char *pathname, + // const struct timespec times[2], int flags); + addToFunctionSummaryMap("utimensat", + Summary(ArgTypes{IntTy, ConstCharPtrTy, + ConstStructTimespecPtrTy, IntTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(1)))); + + Optional StructTimevalTy = lookupTy("timeval"); + Optional ConstStructTimevalPtrTy = + getPointerTy(getConstTy(StructTimevalTy)); + + // int utimes(const char *filename, const struct timeval times[2]); + addToFunctionSummaryMap( + "utimes", Summary(ArgTypes{ConstCharPtrTy, ConstStructTimevalPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); + addToFunctionSummaryMap( + "nanosleep", + Summary(ArgTypes{ConstStructTimespecPtrTy, StructTimespecPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + Optional Time_tTy = lookupTy("time_t"); + Optional ConstTime_tPtrTy = getPointerTy(getConstTy(Time_tTy)); + Optional ConstTime_tPtrRestrictTy = + getRestrictTy(ConstTime_tPtrTy); + + Optional StructTmTy = lookupTy("tm"); + Optional StructTmPtrTy = getPointerTy(StructTmTy); + Optional StructTmPtrRestrictTy = getRestrictTy(StructTmPtrTy); + Optional ConstStructTmPtrTy = + getPointerTy(getConstTy(StructTmTy)); + Optional ConstStructTmPtrRestrictTy = + getRestrictTy(ConstStructTmPtrTy); + + // struct tm * localtime(const time_t *tp); + addToFunctionSummaryMap( + "localtime", + Summary(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // struct tm *localtime_r(const time_t *restrict timer, + // struct tm *restrict result); + addToFunctionSummaryMap( + "localtime_r", + Summary(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy}, + RetType{StructTmPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // char *asctime_r(const struct tm *restrict tm, char *restrict buf); + addToFunctionSummaryMap( + "asctime_r", + Summary(ArgTypes{ConstStructTmPtrRestrictTy, CharPtrRestrictTy}, + RetType{CharPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1), + /*MinBufSize=*/BVF.getValue(26, IntTy)))); + + // char *ctime_r(const time_t *timep, char *buf); + addToFunctionSummaryMap("ctime_r", + Summary(ArgTypes{ConstTime_tPtrTy, CharPtrTy}, + RetType{CharPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(BufferSize( + /*Buffer=*/ArgNo(1), + /*MinBufSize=*/BVF.getValue(26, IntTy)))); + + // struct tm *gmtime_r(const time_t *restrict timer, + // struct tm *restrict result); + addToFunctionSummaryMap( + "gmtime_r", + Summary(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy}, + RetType{StructTmPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // struct tm * gmtime(const time_t *tp); + addToFunctionSummaryMap( + "gmtime", + Summary(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + Optional Clockid_tTy = lookupTy("clockid_t"); + + // int clock_gettime(clockid_t clock_id, struct timespec *tp); + addToFunctionSummaryMap("clock_gettime", + Summary(ArgTypes{Clockid_tTy, StructTimespecPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(1)))); + + Optional StructItimervalTy = lookupTy("itimerval"); + Optional StructItimervalPtrTy = getPointerTy(StructItimervalTy); + + // int getitimer(int which, struct itimerval *curr_value); + addToFunctionSummaryMap("getitimer", + Summary(ArgTypes{IntTy, StructItimervalPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(1)))); + + Optional Pthread_cond_tTy = lookupTy("pthread_cond_t"); + Optional Pthread_cond_tPtrTy = getPointerTy(Pthread_cond_tTy); + Optional Pthread_tTy = lookupTy("pthread_t"); + Optional Pthread_tPtrTy = getPointerTy(Pthread_tTy); + Optional Pthread_tPtrRestrictTy = getRestrictTy(Pthread_tPtrTy); + Optional Pthread_mutex_tTy = lookupTy("pthread_mutex_t"); + Optional Pthread_mutex_tPtrTy = getPointerTy(Pthread_mutex_tTy); + Optional Pthread_mutex_tPtrRestrictTy = + getRestrictTy(Pthread_mutex_tPtrTy); + Optional Pthread_attr_tTy = lookupTy("pthread_attr_t"); + Optional Pthread_attr_tPtrTy = getPointerTy(Pthread_attr_tTy); + Optional ConstPthread_attr_tPtrTy = + getPointerTy(getConstTy(Pthread_attr_tTy)); + Optional ConstPthread_attr_tPtrRestrictTy = + getRestrictTy(ConstPthread_attr_tPtrTy); + Optional Pthread_mutexattr_tTy = lookupTy("pthread_mutexattr_t"); + Optional ConstPthread_mutexattr_tPtrTy = + getPointerTy(getConstTy(Pthread_mutexattr_tTy)); + Optional ConstPthread_mutexattr_tPtrRestrictTy = + getRestrictTy(ConstPthread_mutexattr_tPtrTy); + + QualType PthreadStartRoutineTy = getPointerTy( + ACtx.getFunctionType(/*ResultTy=*/VoidPtrTy, /*Args=*/VoidPtrTy, + FunctionProtoType::ExtProtoInfo())); + + // int pthread_cond_signal(pthread_cond_t *cond); + // int pthread_cond_broadcast(pthread_cond_t *cond); + addToFunctionSummaryMap( + {"pthread_cond_signal", "pthread_cond_broadcast"}, + Signature(ArgTypes{Pthread_cond_tPtrTy}, RetType{IntTy}), + Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0)))); + + // int pthread_create(pthread_t *restrict thread, + // const pthread_attr_t *restrict attr, + // void *(*start_routine)(void*), void *restrict arg); + addToFunctionSummaryMap( + "pthread_create", + Signature(ArgTypes{Pthread_tPtrRestrictTy, + ConstPthread_attr_tPtrRestrictTy, + PthreadStartRoutineTy, VoidPtrRestrictTy}, + RetType{IntTy}), + Summary(NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(2)))); + + // int pthread_attr_destroy(pthread_attr_t *attr); + // int pthread_attr_init(pthread_attr_t *attr); + addToFunctionSummaryMap( + {"pthread_attr_destroy", "pthread_attr_init"}, + Signature(ArgTypes{Pthread_attr_tPtrTy}, RetType{IntTy}), + Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0)))); + + // int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, + // size_t *restrict stacksize); + // int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, + // size_t *restrict guardsize); + addToFunctionSummaryMap( + {"pthread_attr_getstacksize", "pthread_attr_getguardsize"}, + Signature(ArgTypes{ConstPthread_attr_tPtrRestrictTy, SizePtrRestrictTy}, + RetType{IntTy}), + Summary(NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); + // int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); + addToFunctionSummaryMap( + {"pthread_attr_setstacksize", "pthread_attr_setguardsize"}, + Signature(ArgTypes{Pthread_attr_tPtrTy, SizeTy}, RetType{IntTy}), + Summary(NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint( + ArgumentCondition(1, WithinRange, Range(0, SizeMax)))); + + // int pthread_mutex_init(pthread_mutex_t *restrict mutex, const + // pthread_mutexattr_t *restrict attr); + addToFunctionSummaryMap( + "pthread_mutex_init", + Signature(ArgTypes{Pthread_mutex_tPtrRestrictTy, + ConstPthread_mutexattr_tPtrRestrictTy}, + RetType{IntTy}), + Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0)))); + + // int pthread_mutex_destroy(pthread_mutex_t *mutex); + // int pthread_mutex_lock(pthread_mutex_t *mutex); + // int pthread_mutex_trylock(pthread_mutex_t *mutex); + // int pthread_mutex_unlock(pthread_mutex_t *mutex); + addToFunctionSummaryMap( + {"pthread_mutex_destroy", "pthread_mutex_lock", "pthread_mutex_trylock", + "pthread_mutex_unlock"}, + Signature(ArgTypes{Pthread_mutex_tPtrTy}, RetType{IntTy}), + Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0)))); } // Functions for testing. @@ -2048,6 +2312,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( EvalCallAsPure) .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1), /*BufSizeMultiplier=*/ArgNo(2)))); + addToFunctionSummaryMap( + "__buf_size_arg_constraint_concrete", + Summary(ArgTypes{ConstVoidPtrTy}, RetType{IntTy}, EvalCallAsPure) + .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0), + /*BufSize=*/BVF.getValue(10, IntTy)))); + addToFunctionSummaryMap( + {"__test_restrict_param_0", "__test_restrict_param_1", + "__test_restrict_param_2"}, + Signature(ArgTypes{VoidPtrRestrictTy}, RetType{VoidTy}), + Summary(EvalCallAsPure)); } } diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 78d13ddfb773c..a55d9302ca587 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -687,7 +687,7 @@ void CXXInstanceCall::getExtraInvalidatedValues( // base class decl, rather than the class of the instance which needs to be // checked for mutable fields. // TODO: We might as well look at the dynamic type of the object. - const Expr *Ex = getCXXThisExpr()->ignoreParenBaseCasts(); + const Expr *Ex = getCXXThisExpr()->IgnoreParenBaseCasts(); QualType T = Ex->getType(); if (T->isPointerType()) // Arrow or implicit-this syntax? T = T->getPointeeType(); diff --git a/clang/lib/Tooling/Transformer/RewriteRule.cpp b/clang/lib/Tooling/Transformer/RewriteRule.cpp index fe33f9cf8b0ca..03921e0ea7de5 100644 --- a/clang/lib/Tooling/Transformer/RewriteRule.cpp +++ b/clang/lib/Tooling/Transformer/RewriteRule.cpp @@ -242,7 +242,7 @@ class ApplyRuleCallback : public MatchFinder::MatchCallback { } // namespace template -static llvm::Expected> +llvm::Expected> rewriteDescendantsImpl(const T &Node, RewriteRule Rule, const MatchResult &Result) { ApplyRuleCallback Callback(std::move(Rule)); @@ -252,10 +252,43 @@ rewriteDescendantsImpl(const T &Node, RewriteRule Rule, return std::move(Callback.Edits); } +llvm::Expected> +transformer::detail::rewriteDescendants(const Decl &Node, RewriteRule Rule, + const MatchResult &Result) { + return rewriteDescendantsImpl(Node, std::move(Rule), Result); +} + +llvm::Expected> +transformer::detail::rewriteDescendants(const Stmt &Node, RewriteRule Rule, + const MatchResult &Result) { + return rewriteDescendantsImpl(Node, std::move(Rule), Result); +} + +llvm::Expected> +transformer::detail::rewriteDescendants(const TypeLoc &Node, RewriteRule Rule, + const MatchResult &Result) { + return rewriteDescendantsImpl(Node, std::move(Rule), Result); +} + +llvm::Expected> +transformer::detail::rewriteDescendants(const DynTypedNode &DNode, + RewriteRule Rule, + const MatchResult &Result) { + if (const auto *Node = DNode.get()) + return rewriteDescendantsImpl(*Node, std::move(Rule), Result); + if (const auto *Node = DNode.get()) + return rewriteDescendantsImpl(*Node, std::move(Rule), Result); + if (const auto *Node = DNode.get()) + return rewriteDescendantsImpl(*Node, std::move(Rule), Result); + + return llvm::make_error( + llvm::errc::invalid_argument, + "type unsupported for recursive rewriting, Kind=" + + DNode.getNodeKind().asStringRef()); +} + EditGenerator transformer::rewriteDescendants(std::string NodeId, RewriteRule Rule) { - // FIXME: warn or return error if `Rule` contains any `AddedIncludes`, since - // these will be dropped. return [NodeId = std::move(NodeId), Rule = std::move(Rule)](const MatchResult &Result) -> llvm::Expected> { @@ -265,17 +298,7 @@ EditGenerator transformer::rewriteDescendants(std::string NodeId, if (It == NodesMap.end()) return llvm::make_error(llvm::errc::invalid_argument, "ID not bound: " + NodeId); - if (auto *Node = It->second.get()) - return rewriteDescendantsImpl(*Node, std::move(Rule), Result); - if (auto *Node = It->second.get()) - return rewriteDescendantsImpl(*Node, std::move(Rule), Result); - if (auto *Node = It->second.get()) - return rewriteDescendantsImpl(*Node, std::move(Rule), Result); - - return llvm::make_error( - llvm::errc::invalid_argument, - "type unsupported for recursive rewriting, ID=\"" + NodeId + - "\", Kind=" + It->second.getNodeKind().asStringRef()); + return detail::rewriteDescendants(It->second, std::move(Rule), Result); }; } @@ -345,14 +368,13 @@ transformer::detail::buildMatchers(const RewriteRule &Rule) { // Each anyOf explicitly controls the traversal kind. The anyOf itself is set // to `TK_AsIs` to ensure no nodes are skipped, thereby deferring to the kind // of the branches. Then, each branch is either left as is, if the kind is - // already set, or explicitly set to `TK_IgnoreUnlessSpelledInSource`. We - // choose this setting, because we think it is the one most friendly to - // beginners, who are (largely) the target audience of Transformer. + // already set, or explicitly set to `TK_AsIs`. We choose this setting because + // it is the default interpretation of matchers. std::vector Matchers; for (const auto &Bucket : Buckets) { DynTypedMatcher M = DynTypedMatcher::constructVariadic( DynTypedMatcher::VO_AnyOf, Bucket.first, - taggedMatchers("Tag", Bucket.second, TK_IgnoreUnlessSpelledInSource)); + taggedMatchers("Tag", Bucket.second, TK_AsIs)); M.setAllowBind(true); // `tryBind` is guaranteed to succeed, because `AllowBind` was set to true. Matchers.push_back(M.tryBind(RootID)->withTraversalKind(TK_AsIs)); diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp b/clang/test/AST/ast-dump-fpfeatures.cpp index 796b0a0283828..f3925aebbe752 100644 --- a/clang/test/AST/ast-dump-fpfeatures.cpp +++ b/clang/test/AST/ast-dump-fpfeatures.cpp @@ -34,4 +34,69 @@ float func_03(float x) { // CHECK-NEXT: ParmVarDecl {{.*}} x 'float' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: ReturnStmt -// CHECK-NEXT: CallExpr {{.*}} FPContractMode=0 \ No newline at end of file +// CHECK-NEXT: CallExpr {{.*}} FPContractMode=0 + + + + +#pragma STDC FENV_ROUND FE_DOWNWARD + +float func_10(float x, float y) { + return x + y; +} + +// CHECK-LABEL: FunctionDecl {{.*}} func_10 'float (float, float)' +// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=3 + +float func_11(float x, float y) { + if (x < 0) { + #pragma STDC FENV_ROUND FE_UPWARD + return x + y; + } + return x - y; +} + +// CHECK-LABEL: FunctionDecl {{.*}} func_11 'float (float, float)' +// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=2 +// CHECK: BinaryOperator {{.*}} 'float' '-' RoundingMode=3 + + +#pragma STDC FENV_ROUND FE_DYNAMIC + +float func_12(float x, float y) { + return x + y; +} + +// CHECK-LABEL: FunctionDecl {{.*}} func_12 'float (float, float)' +// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=1 + +#pragma STDC FENV_ROUND FE_TONEAREST + +float func_13(float x, float y) { + return x + y; +} + +// CHECK-LABEL: FunctionDecl {{.*}} func_13 'float (float, float)' +// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=1 + + +template +T func_14(T x, T y) { +#pragma STDC FENV_ROUND FE_TOWARDZERO + return x + y; +} + +float func_15(float x, float y) { +#pragma STDC FPENV_ROUND FE_DOWNWARD + return func_14(x, y); +} + +// CHECK-LABEL: FunctionTemplateDecl {{.*}} func_14 +// CHECK: FunctionDecl {{.*}} func_14 'T (T, T)' +// CHECK: CompoundStmt +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: BinaryOperator {{.*}} '+' RoundingMode=0 +// CHECK: FunctionDecl {{.*}} func_14 'float (float, float)' +// CHECK: CompoundStmt +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' RoundingMode=0 diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index 7c00e78c16acd..bef786a1a59b6 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -6,11 +6,11 @@ // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List // CHECK-EMPTY: -// CHECK-NEXT: core.CallAndMessageModeling // CHECK-NEXT: apiModeling.StdCLibraryFunctions // CHECK-NEXT: apiModeling.TrustNonnull // CHECK-NEXT: apiModeling.llvm.CastValue // CHECK-NEXT: apiModeling.llvm.ReturnValue +// CHECK-NEXT: core.CallAndMessageModeling // CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: core.DivideZero // CHECK-NEXT: core.DynamicTypePropagation diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c index 3638ad100240a..c2c98df864899 100644 --- a/clang/test/Analysis/std-c-library-functions-POSIX.c +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -95,6 +95,33 @@ // CHECK: Loaded summary for: ssize_t send(int sockfd, const void *buf, size_t len, int flags) // CHECK: Loaded summary for: int socketpair(int domain, int type, int protocol, int sv[2]) // CHECK: Loaded summary for: int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags) +// CHECK: Loaded summary for: int utime(const char *filename, struct utimbuf *buf) +// CHECK: Loaded summary for: int futimens(int fd, const struct timespec times[2]) +// CHECK: Loaded summary for: int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags) +// CHECK: Loaded summary for: int utimes(const char *filename, const struct timeval times[2]) +// CHECK: Loaded summary for: int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +// CHECK: Loaded summary for: struct tm *localtime(const time_t *tp) +// CHECK: Loaded summary for: struct tm *localtime_r(const time_t *restrict timer, struct tm *restrict result) +// CHECK: Loaded summary for: char *asctime_r(const struct tm *restrict tm, char *restrict buf) +// CHECK: Loaded summary for: char *ctime_r(const time_t *timep, char *buf) +// CHECK: Loaded summary for: struct tm *gmtime_r(const time_t *restrict timer, struct tm *restrict result) +// CHECK: Loaded summary for: struct tm *gmtime(const time_t *tp) +// CHECK: Loaded summary for: int clock_gettime(clockid_t clock_id, struct timespec *tp) +// CHECK: Loaded summary for: int getitimer(int which, struct itimerval *curr_value) +// CHECK: Loaded summary for: int pthread_cond_signal(pthread_cond_t *cond) +// CHECK: Loaded summary for: int pthread_cond_broadcast(pthread_cond_t *cond) +// CHECK: Loaded summary for: int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg) +// CHECK: Loaded summary for: int pthread_attr_destroy(pthread_attr_t *attr) +// CHECK: Loaded summary for: int pthread_attr_init(pthread_attr_t *attr) +// CHECK: Loaded summary for: int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, size_t *restrict stacksize) +// CHECK: Loaded summary for: int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize) +// CHECK: Loaded summary for: int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) +// CHECK: Loaded summary for: int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) +// CHECK: Loaded summary for: int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr) +// CHECK: Loaded summary for: int pthread_mutex_destroy(pthread_mutex_t *mutex) +// CHECK: Loaded summary for: int pthread_mutex_lock(pthread_mutex_t *mutex) +// CHECK: Loaded summary for: int pthread_mutex_trylock(pthread_mutex_t *mutex) +// CHECK: Loaded summary for: int pthread_mutex_unlock(pthread_mutex_t *mutex) long a64l(const char *str64); char *l64a(long value); @@ -226,6 +253,53 @@ int getsockopt(int socket, int level, int option_name, void *restrict option_val ssize_t send(int sockfd, const void *buf, size_t len, int flags); int socketpair(int domain, int type, int protocol, int sv[2]); int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags); +struct utimbuf; +struct timespec { int x; }; +struct timeval { int x; }; +int utime(const char *filename, struct utimbuf *buf); +int futimens(int fd, const struct timespec times[2]); +int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags); +int utimes(const char *filename, const struct timeval times[2]); +int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); +typedef unsigned long time_t; +struct tm *localtime(const time_t *tp); +struct tm *localtime_r(const time_t *restrict timer, struct tm *restrict result); +char *asctime_r(const struct tm *restrict tm, char *restrict buf); +char *ctime_r(const time_t *timep, char *buf); +struct tm *gmtime_r(const time_t *restrict timer, struct tm *restrict result); +struct tm *gmtime(const time_t *tp); +typedef unsigned long clockid_t; +int clock_gettime(clockid_t clock_id, struct timespec *tp); +struct itimerval; +int getitimer(int which, struct itimerval *curr_value); + +typedef union { + int x; +} pthread_cond_t; +int pthread_cond_signal(pthread_cond_t *cond); +int pthread_cond_broadcast(pthread_cond_t *cond); +typedef union { + int x; +} pthread_attr_t; +typedef unsigned long int pthread_t; +int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg); +int pthread_attr_destroy(pthread_attr_t *attr); +int pthread_attr_init(pthread_attr_t *attr); +int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, size_t *restrict stacksize); +int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize); +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); +typedef union { + int x; +} pthread_mutex_t; +typedef union { + int x; +} pthread_mutexattr_t; +int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); +int pthread_mutex_destroy(pthread_mutex_t *mutex); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); // Must have at least one call expression to initialize the summary map. int bar(void); diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints.c b/clang/test/Analysis/std-c-library-functions-arg-constraints.c index e926cd15384d1..28979abd43b58 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-constraints.c +++ b/clang/test/Analysis/std-c-library-functions-arg-constraints.c @@ -256,6 +256,7 @@ void test_buf_size_symbolic_and_offset(int s) { // bugpath-note{{TRUE}} \ // bugpath-note{{'s' is <= 2}} } + int __buf_size_arg_constraint_mul(const void *, size_t, size_t); void test_buf_size_concrete_with_multiplication() { short buf[3]; // bugpath-note{{'buf' initialized here}} @@ -280,3 +281,13 @@ void test_buf_size_symbolic_and_offset_with_multiplication(size_t s) { // bugpath-warning{{TRUE}} \ // bugpath-note{{TRUE}} } + +// The minimum buffer size for this function is set to 10. +int __buf_size_arg_constraint_concrete(const void *); +void test_min_buf_size() { + char buf[9];// bugpath-note{{'buf' initialized here}} + __buf_size_arg_constraint_concrete(buf); // \ + // report-warning{{Function argument constraint is not satisfied}} \ + // bugpath-warning{{Function argument constraint is not satisfied}} \ + // bugpath-note{{Function argument constraint is not satisfied}} +} diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c new file mode 100644 index 0000000000000..9ad1be0538517 --- /dev/null +++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -0,0 +1,66 @@ +// Here we test the order of the Checkers when StdCLibraryFunctionArgs is +// enabled. + +// RUN: %clang --analyze %s --target=x86_64-pc-linux-gnu \ +// RUN: -Xclang -analyzer-checker=core \ +// RUN: -Xclang -analyzer-checker=apiModeling.StdCLibraryFunctions \ +// RUN: -Xclang -analyzer-config \ +// RUN: -Xclang apiModeling.StdCLibraryFunctions:ModelPOSIX=true \ +// RUN: -Xclang -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \ +// RUN: -Xclang -analyzer-checker=alpha.unix.Stream \ +// RUN: -Xclang -analyzer-list-enabled-checkers \ +// RUN: -Xclang -analyzer-display-progress \ +// RUN: 2>&1 | FileCheck %s --implicit-check-not=ANALYZE \ +// RUN: --implicit-check-not=\. + +// CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List +// CHECK-EMPTY: +// CHECK-NEXT: core.CallAndMessageModeling +// CHECK-NEXT: core.CallAndMessage +// CHECK-NEXT: core.NonNullParamChecker +// CHECK-NEXT: alpha.unix.Stream +// CHECK-NEXT: apiModeling.StdCLibraryFunctions +// CHECK-NEXT: alpha.unix.StdCLibraryFunctionArgs +// CHECK-NEXT: apiModeling.TrustNonnull +// CHECK-NEXT: apiModeling.llvm.CastValue +// CHECK-NEXT: apiModeling.llvm.ReturnValue +// CHECK-NEXT: core.DivideZero +// CHECK-NEXT: core.DynamicTypePropagation +// CHECK-NEXT: core.NonnilStringConstants +// CHECK-NEXT: core.NullDereference +// CHECK-NEXT: core.StackAddrEscapeBase +// CHECK-NEXT: core.StackAddressEscape +// CHECK-NEXT: core.UndefinedBinaryOperatorResult +// CHECK-NEXT: core.VLASize +// CHECK-NEXT: core.builtin.BuiltinFunctions +// CHECK-NEXT: core.builtin.NoReturnFunctions +// CHECK-NEXT: core.uninitialized.ArraySubscript +// CHECK-NEXT: core.uninitialized.Assign +// CHECK-NEXT: core.uninitialized.Branch +// CHECK-NEXT: core.uninitialized.CapturedBlockVariable +// CHECK-NEXT: core.uninitialized.UndefReturn +// CHECK-NEXT: deadcode.DeadStores +// CHECK-NEXT: nullability.NullabilityBase +// CHECK-NEXT: nullability.NullPassedToNonnull +// CHECK-NEXT: nullability.NullReturnedFromNonnull +// CHECK-NEXT: security.insecureAPI.SecuritySyntaxChecker +// CHECK-NEXT: security.insecureAPI.UncheckedReturn +// CHECK-NEXT: security.insecureAPI.getpw +// CHECK-NEXT: security.insecureAPI.gets +// CHECK-NEXT: security.insecureAPI.mkstemp +// CHECK-NEXT: security.insecureAPI.mktemp +// CHECK-NEXT: security.insecureAPI.vfork +// CHECK-NEXT: unix.API +// CHECK-NEXT: unix.cstring.CStringModeling +// CHECK-NEXT: unix.DynamicMemoryModeling +// CHECK-NEXT: unix.Malloc +// CHECK-NEXT: unix.MallocSizeof +// CHECK-NEXT: unix.MismatchedDeallocator +// CHECK-NEXT: unix.Vfork +// CHECK-NEXT: unix.cstring.BadSizeArg +// CHECK-NEXT: unix.cstring.NullArg + +int main() { + int i; + (void)(10 / i); +} diff --git a/clang/test/Analysis/std-c-library-functions-arg-weakdeps.c b/clang/test/Analysis/std-c-library-functions-arg-weakdeps.c new file mode 100644 index 0000000000000..0ad3c277dfd7d --- /dev/null +++ b/clang/test/Analysis/std-c-library-functions-arg-weakdeps.c @@ -0,0 +1,64 @@ +// Check that the more specific checkers report and not the generic +// StdCLibraryFunctionArgs checker. + +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ +// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true \ +// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=alpha.unix.Stream \ +// RUN: -triple x86_64-unknown-linux-gnu \ +// RUN: -verify + + +// Make sure that all used functions have their summary loaded. + +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ +// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true \ +// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=alpha.unix.Stream \ +// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries=true \ +// RUN: -triple x86_64-unknown-linux 2>&1 | FileCheck %s + +// CHECK: Loaded summary for: int isalnum(int) +// CHECK: Loaded summary for: unsigned long fread(void *restrict, size_t, size_t, FILE *restrict) __attribute__((nonnull(1))) +// CHECK: Loaded summary for: int fileno(FILE *stream) + +void initializeSummaryMap(); +// We analyze this function first, and the call expression inside initializes +// the summary map. This way we force the loading of the summaries. The +// summaries would not be loaded without this because during the first bug +// report in WeakDependency::checkPreCall we stop further evaluation. And +// StdLibraryFunctionsChecker lazily initializes its summary map from its +// checkPreCall. +void analyzeThisFirst() { + initializeSummaryMap(); +} + +typedef __typeof(sizeof(int)) size_t; +struct FILE; +typedef struct FILE FILE; + +int isalnum(int); +size_t fread(void *restrict, size_t, size_t, FILE *restrict) __attribute__((nonnull(1))); +int fileno(FILE *stream); + +void test_uninit_arg() { + int v; + int r = isalnum(v); // \ + // expected-warning{{1st function call argument is an uninitialized value [core.CallAndMessage]}} + (void)r; +} + +void test_notnull_arg(FILE *F) { + int *p = 0; + fread(p, sizeof(int), 5, F); // \ + expected-warning{{Null pointer passed to 1st parameter expecting 'nonnull' [core.NonNullParamChecker]}} +} + +void test_notnull_stream_arg() { + fileno(0); // \ + // expected-warning{{Stream pointer might be NULL [alpha.unix.Stream]}} +} diff --git a/clang/test/Analysis/std-c-library-functions-restrict.c b/clang/test/Analysis/std-c-library-functions-restrict.c new file mode 100644 index 0000000000000..7cf5f2bc630a3 --- /dev/null +++ b/clang/test/Analysis/std-c-library-functions-restrict.c @@ -0,0 +1,24 @@ +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ +// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ +// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries=true \ +// RUN: -triple i686-unknown-linux 2>&1 | FileCheck %s + +// The signatures for these functions are the same and they specify their +// parameter with the restrict qualifier. In C, the signature should match only +// if the restrict qualifier is there on the parameter. Thus, the summary +// should be loaded for the last two declarations only. +void __test_restrict_param_0(void *p); +void __test_restrict_param_1(void *__restrict p); +void __test_restrict_param_2(void *restrict p); + +// CHECK-NOT: Loaded summary for: void __test_restrict_param_0 +// CHECK: Loaded summary for: void __test_restrict_param_1(void *restrict p) +// CHECK: Loaded summary for: void __test_restrict_param_2(void *restrict p) + +// Must have at least one call expression to initialize the summary map. +int bar(void); +void foo() { + bar(); +} diff --git a/clang/test/Analysis/std-c-library-functions-restrict.cpp b/clang/test/Analysis/std-c-library-functions-restrict.cpp new file mode 100644 index 0000000000000..d1cd090f5ef85 --- /dev/null +++ b/clang/test/Analysis/std-c-library-functions-restrict.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ +// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ +// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries=true \ +// RUN: -triple i686-unknown-linux 2>&1 | FileCheck %s + +// The signatures for these functions are the same and they specify their +// parameter with the restrict qualifier. In C++, however, we are more +// indulgent and we do not match based on this qualifier. Thus, the given +// signature should match for both of the declarations below, i.e the summary +// should be loaded for both of them. +void __test_restrict_param_0(void *p); +void __test_restrict_param_1(void *__restrict p); +// The below declaration is illegal, "restrict" is not a keyword in C++. +// void __test_restrict_param_2(void *restrict p); + +// CHECK: Loaded summary for: void __test_restrict_param_0(void *p) +// CHECK: Loaded summary for: void __test_restrict_param_1(void *__restrict p) + +// Must have at least one call expression to initialize the summary map. +int bar(void); +void foo() { + bar(); +} diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c index 03ab37474ba02..a656657b66197 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include @@ -9,8 +9,8 @@ // CHECK-NEXT: [[TMP0:%.*]] = icmp slt <16 x i8> [[B:%.*]], zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = sub <16 x i8> zeroinitializer, [[B]] // CHECK-NEXT: [[TMP2:%.*]] = select <16 x i1> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[B]] -// CHECK-NEXT: [[TMP3:%.*]] = icmp ugt <16 x i8> [[TMP2]], [[A:%.*]] -// CHECK-NEXT: [[TMP4:%.*]] = select <16 x i1> [[TMP3]], <16 x i8> [[TMP2]], <16 x i8> [[A]] +// CHECK-NEXT: [[TMP3:%.*]] = icmp uge <16 x i8> [[A:%.*]], [[TMP2]] +// CHECK-NEXT: [[TMP4:%.*]] = select <16 x i1> [[TMP3]], <16 x i8> [[A]], <16 x i8> [[TMP2]] // CHECK-NEXT: ret <16 x i8> [[TMP4]] // uint8x16_t test_vmaxaq_s8(uint8x16_t a, int8x16_t b) @@ -27,8 +27,8 @@ uint8x16_t test_vmaxaq_s8(uint8x16_t a, int8x16_t b) // CHECK-NEXT: [[TMP0:%.*]] = icmp slt <8 x i16> [[B:%.*]], zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = sub <8 x i16> zeroinitializer, [[B]] // CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[B]] -// CHECK-NEXT: [[TMP3:%.*]] = icmp ugt <8 x i16> [[TMP2]], [[A:%.*]] -// CHECK-NEXT: [[TMP4:%.*]] = select <8 x i1> [[TMP3]], <8 x i16> [[TMP2]], <8 x i16> [[A]] +// CHECK-NEXT: [[TMP3:%.*]] = icmp uge <8 x i16> [[A:%.*]], [[TMP2]] +// CHECK-NEXT: [[TMP4:%.*]] = select <8 x i1> [[TMP3]], <8 x i16> [[A]], <8 x i16> [[TMP2]] // CHECK-NEXT: ret <8 x i16> [[TMP4]] // uint16x8_t test_vmaxaq_s16(uint16x8_t a, int16x8_t b) @@ -45,8 +45,8 @@ uint16x8_t test_vmaxaq_s16(uint16x8_t a, int16x8_t b) // CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[B:%.*]], zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> zeroinitializer, [[B]] // CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[B]] -// CHECK-NEXT: [[TMP3:%.*]] = icmp ugt <4 x i32> [[TMP2]], [[A:%.*]] -// CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[TMP2]], <4 x i32> [[A]] +// CHECK-NEXT: [[TMP3:%.*]] = icmp uge <4 x i32> [[A:%.*]], [[TMP2]] +// CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[A]], <4 x i32> [[TMP2]] // CHECK-NEXT: ret <4 x i32> [[TMP4]] // uint32x4_t test_vmaxaq_s32(uint32x4_t a, int32x4_t b) @@ -61,8 +61,8 @@ uint32x4_t test_vmaxaq_s32(uint32x4_t a, int32x4_t b) // CHECK-LABEL: @test_vmaxaq_m_s8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.arm.mve.vmaxa.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.vmaxa.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]]) // CHECK-NEXT: ret <16 x i8> [[TMP2]] // uint8x16_t test_vmaxaq_m_s8(uint8x16_t a, int8x16_t b, mve_pred16_t p) @@ -77,8 +77,8 @@ uint8x16_t test_vmaxaq_m_s8(uint8x16_t a, int8x16_t b, mve_pred16_t p) // CHECK-LABEL: @test_vmaxaq_m_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.arm.mve.vmaxa.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.vmaxa.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]]) // CHECK-NEXT: ret <8 x i16> [[TMP2]] // uint16x8_t test_vmaxaq_m_s16(uint16x8_t a, int16x8_t b, mve_pred16_t p) @@ -93,8 +93,8 @@ uint16x8_t test_vmaxaq_m_s16(uint16x8_t a, int16x8_t b, mve_pred16_t p) // CHECK-LABEL: @test_vmaxaq_m_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.arm.mve.vmaxa.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.vmaxa.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]]) // CHECK-NEXT: ret <4 x i32> [[TMP2]] // uint32x4_t test_vmaxaq_m_s32(uint32x4_t a, int32x4_t b, mve_pred16_t p) diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c index 20c22056d52a5..52b439fe5555f 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c @@ -1,14 +1,14 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include // CHECK-LABEL: @test_vmaxnmaq_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x half> @llvm.fabs.v8f16(<8 x half> [[A:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.fabs.v8f16(<8 x half> [[B:%.*]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x half> @llvm.maxnum.v8f16(<8 x half> [[TMP0]], <8 x half> [[TMP1]]) +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x half> @llvm.fabs.v8f16(<8 x half> [[A:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x half> @llvm.fabs.v8f16(<8 x half> [[B:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x half> @llvm.maxnum.v8f16(<8 x half> [[TMP0]], <8 x half> [[TMP1]]) // CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vmaxnmaq_f16(float16x8_t a, float16x8_t b) @@ -22,9 +22,9 @@ float16x8_t test_vmaxnmaq_f16(float16x8_t a, float16x8_t b) // CHECK-LABEL: @test_vmaxnmaq_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> [[A:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> [[B:%.*]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.fabs.v4f32(<4 x float> [[A:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x float> @llvm.fabs.v4f32(<4 x float> [[B:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) // CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vmaxnmaq_f32(float32x4_t a, float32x4_t b) @@ -39,8 +39,8 @@ float32x4_t test_vmaxnmaq_f32(float32x4_t a, float32x4_t b) // CHECK-LABEL: @test_vmaxnmaq_m_f16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x half> @llvm.arm.mve.vmaxnma.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], <8 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x half> @llvm.arm.mve.vmaxnma.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], <8 x i1> [[TMP1]]) // CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vmaxnmaq_m_f16(float16x8_t a, float16x8_t b, mve_pred16_t p) @@ -55,8 +55,8 @@ float16x8_t test_vmaxnmaq_m_f16(float16x8_t a, float16x8_t b, mve_pred16_t p) // CHECK-LABEL: @test_vmaxnmaq_m_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.arm.mve.vmaxnma.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], <4 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x float> @llvm.arm.mve.vmaxnma.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], <4 x i1> [[TMP1]]) // CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vmaxnmaq_m_f32(float32x4_t a, float32x4_t b, mve_pred16_t p) diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c index 5caf8d6421feb..19b5d28a52440 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c @@ -1,12 +1,12 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include // CHECK-LABEL: @test_vmaxnmq_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x half> @llvm.maxnum.v8f16(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x half> @llvm.maxnum.v8f16(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]]) // CHECK-NEXT: ret <8 x half> [[TMP0]] // float16x8_t test_vmaxnmq_f16(float16x8_t a, float16x8_t b) @@ -20,7 +20,7 @@ float16x8_t test_vmaxnmq_f16(float16x8_t a, float16x8_t b) // CHECK-LABEL: @test_vmaxnmq_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]]) // CHECK-NEXT: ret <4 x float> [[TMP0]] // float32x4_t test_vmaxnmq_f32(float32x4_t a, float32x4_t b) @@ -35,8 +35,8 @@ float32x4_t test_vmaxnmq_f32(float32x4_t a, float32x4_t b) // CHECK-LABEL: @test_vmaxnmq_m_f16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x half> @llvm.arm.mve.max.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x half> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x half> @llvm.arm.mve.max.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x half> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vmaxnmq_m_f16(float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p) @@ -51,8 +51,8 @@ float16x8_t test_vmaxnmq_m_f16(float16x8_t inactive, float16x8_t a, float16x8_t // CHECK-LABEL: @test_vmaxnmq_m_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.arm.mve.max.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x float> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x float> @llvm.arm.mve.max.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x float> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vmaxnmq_m_f32(float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p) @@ -67,8 +67,8 @@ float32x4_t test_vmaxnmq_m_f32(float32x4_t inactive, float32x4_t a, float32x4_t // CHECK-LABEL: @test_vmaxnmq_x_f16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x half> @llvm.arm.mve.max.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x half> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x half> @llvm.arm.mve.max.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x half> undef) // CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vmaxnmq_x_f16(float16x8_t a, float16x8_t b, mve_pred16_t p) @@ -83,8 +83,8 @@ float16x8_t test_vmaxnmq_x_f16(float16x8_t a, float16x8_t b, mve_pred16_t p) // CHECK-LABEL: @test_vmaxnmq_x_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.arm.mve.max.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x float> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x float> @llvm.arm.mve.max.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x float> undef) // CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vmaxnmq_x_f32(float32x4_t a, float32x4_t b, mve_pred16_t p) diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c index d0ddc7a99e9f8..7fb2f5191f440 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c @@ -1,13 +1,13 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include // CHECK-LABEL: @test_vmaxq_s8( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = icmp slt <16 x i8> [[A:%.*]], [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = select <16 x i1> [[TMP0]], <16 x i8> [[B]], <16 x i8> [[A]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp sge <16 x i8> [[A:%.*]], [[B:%.*]] +// CHECK-NEXT: [[TMP1:%.*]] = select <16 x i1> [[TMP0]], <16 x i8> [[A]], <16 x i8> [[B]] // CHECK-NEXT: ret <16 x i8> [[TMP1]] // int8x16_t test_vmaxq_s8(int8x16_t a, int8x16_t b) @@ -21,8 +21,8 @@ int8x16_t test_vmaxq_s8(int8x16_t a, int8x16_t b) // CHECK-LABEL: @test_vmaxq_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = icmp ult <8 x i16> [[A:%.*]], [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = select <8 x i1> [[TMP0]], <8 x i16> [[B]], <8 x i16> [[A]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp uge <8 x i16> [[A:%.*]], [[B:%.*]] +// CHECK-NEXT: [[TMP1:%.*]] = select <8 x i1> [[TMP0]], <8 x i16> [[A]], <8 x i16> [[B]] // CHECK-NEXT: ret <8 x i16> [[TMP1]] // uint16x8_t test_vmaxq_u16(uint16x8_t a, uint16x8_t b) @@ -36,8 +36,8 @@ uint16x8_t test_vmaxq_u16(uint16x8_t a, uint16x8_t b) // CHECK-LABEL: @test_vmaxq_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[A:%.*]], [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[B]], <4 x i32> [[A]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp sge <4 x i32> [[A:%.*]], [[B:%.*]] +// CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[A]], <4 x i32> [[B]] // CHECK-NEXT: ret <4 x i32> [[TMP1]] // int32x4_t test_vmaxq_s32(int32x4_t a, int32x4_t b) @@ -52,8 +52,8 @@ int32x4_t test_vmaxq_s32(int32x4_t a, int32x4_t b) // CHECK-LABEL: @test_vmaxq_m_u8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.arm.mve.max.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 1, <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.max.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 1, <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <16 x i8> [[TMP2]] // uint8x16_t test_vmaxq_m_u8(uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p) @@ -68,8 +68,8 @@ uint8x16_t test_vmaxq_m_u8(uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_ // CHECK-LABEL: @test_vmaxq_m_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.arm.mve.max.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.max.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <8 x i16> [[TMP2]] // int16x8_t test_vmaxq_m_s16(int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p) @@ -84,8 +84,8 @@ int16x8_t test_vmaxq_m_s16(int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pre // CHECK-LABEL: @test_vmaxq_m_u32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.arm.mve.max.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 1, <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.max.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 1, <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <4 x i32> [[TMP2]] // uint32x4_t test_vmaxq_m_u32(uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p) @@ -100,8 +100,8 @@ uint32x4_t test_vmaxq_m_u32(uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve // CHECK-LABEL: @test_vmaxq_x_u8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.arm.mve.max.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 1, <16 x i1> [[TMP1]], <16 x i8> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.max.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 1, <16 x i1> [[TMP1]], <16 x i8> undef) // CHECK-NEXT: ret <16 x i8> [[TMP2]] // uint8x16_t test_vmaxq_x_u8(uint8x16_t a, uint8x16_t b, mve_pred16_t p) @@ -116,8 +116,8 @@ uint8x16_t test_vmaxq_x_u8(uint8x16_t a, uint8x16_t b, mve_pred16_t p) // CHECK-LABEL: @test_vmaxq_x_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.arm.mve.max.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], i32 1, <8 x i1> [[TMP1]], <8 x i16> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.max.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], i32 1, <8 x i1> [[TMP1]], <8 x i16> undef) // CHECK-NEXT: ret <8 x i16> [[TMP2]] // uint16x8_t test_vmaxq_x_u16(uint16x8_t a, uint16x8_t b, mve_pred16_t p) @@ -132,8 +132,8 @@ uint16x8_t test_vmaxq_x_u16(uint16x8_t a, uint16x8_t b, mve_pred16_t p) // CHECK-LABEL: @test_vmaxq_x_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.arm.mve.max.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x i32> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.max.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x i32> undef) // CHECK-NEXT: ret <4 x i32> [[TMP2]] // int32x4_t test_vmaxq_x_s32(int32x4_t a, int32x4_t b, mve_pred16_t p) diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminaq.c index b23dc1a27be86..6a6279cce0df2 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminaq.c @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include @@ -9,8 +9,8 @@ // CHECK-NEXT: [[TMP0:%.*]] = icmp slt <16 x i8> [[B:%.*]], zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = sub <16 x i8> zeroinitializer, [[B]] // CHECK-NEXT: [[TMP2:%.*]] = select <16 x i1> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[B]] -// CHECK-NEXT: [[TMP3:%.*]] = icmp ult <16 x i8> [[TMP2]], [[A:%.*]] -// CHECK-NEXT: [[TMP4:%.*]] = select <16 x i1> [[TMP3]], <16 x i8> [[TMP2]], <16 x i8> [[A]] +// CHECK-NEXT: [[TMP3:%.*]] = icmp ule <16 x i8> [[A:%.*]], [[TMP2]] +// CHECK-NEXT: [[TMP4:%.*]] = select <16 x i1> [[TMP3]], <16 x i8> [[A]], <16 x i8> [[TMP2]] // CHECK-NEXT: ret <16 x i8> [[TMP4]] // uint8x16_t test_vminaq_s8(uint8x16_t a, int8x16_t b) @@ -27,8 +27,8 @@ uint8x16_t test_vminaq_s8(uint8x16_t a, int8x16_t b) // CHECK-NEXT: [[TMP0:%.*]] = icmp slt <8 x i16> [[B:%.*]], zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = sub <8 x i16> zeroinitializer, [[B]] // CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[B]] -// CHECK-NEXT: [[TMP3:%.*]] = icmp ult <8 x i16> [[TMP2]], [[A:%.*]] -// CHECK-NEXT: [[TMP4:%.*]] = select <8 x i1> [[TMP3]], <8 x i16> [[TMP2]], <8 x i16> [[A]] +// CHECK-NEXT: [[TMP3:%.*]] = icmp ule <8 x i16> [[A:%.*]], [[TMP2]] +// CHECK-NEXT: [[TMP4:%.*]] = select <8 x i1> [[TMP3]], <8 x i16> [[A]], <8 x i16> [[TMP2]] // CHECK-NEXT: ret <8 x i16> [[TMP4]] // uint16x8_t test_vminaq_s16(uint16x8_t a, int16x8_t b) @@ -45,8 +45,8 @@ uint16x8_t test_vminaq_s16(uint16x8_t a, int16x8_t b) // CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[B:%.*]], zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> zeroinitializer, [[B]] // CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[B]] -// CHECK-NEXT: [[TMP3:%.*]] = icmp ult <4 x i32> [[TMP2]], [[A:%.*]] -// CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[TMP2]], <4 x i32> [[A]] +// CHECK-NEXT: [[TMP3:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[TMP2]] +// CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[A]], <4 x i32> [[TMP2]] // CHECK-NEXT: ret <4 x i32> [[TMP4]] // uint32x4_t test_vminaq_s32(uint32x4_t a, int32x4_t b) @@ -61,8 +61,8 @@ uint32x4_t test_vminaq_s32(uint32x4_t a, int32x4_t b) // CHECK-LABEL: @test_vminaq_m_s8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.arm.mve.vmina.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.vmina.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]]) // CHECK-NEXT: ret <16 x i8> [[TMP2]] // uint8x16_t test_vminaq_m_s8(uint8x16_t a, int8x16_t b, mve_pred16_t p) @@ -77,8 +77,8 @@ uint8x16_t test_vminaq_m_s8(uint8x16_t a, int8x16_t b, mve_pred16_t p) // CHECK-LABEL: @test_vminaq_m_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.arm.mve.vmina.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.vmina.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]]) // CHECK-NEXT: ret <8 x i16> [[TMP2]] // uint16x8_t test_vminaq_m_s16(uint16x8_t a, int16x8_t b, mve_pred16_t p) @@ -93,8 +93,8 @@ uint16x8_t test_vminaq_m_s16(uint16x8_t a, int16x8_t b, mve_pred16_t p) // CHECK-LABEL: @test_vminaq_m_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.arm.mve.vmina.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.vmina.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]]) // CHECK-NEXT: ret <4 x i32> [[TMP2]] // uint32x4_t test_vminaq_m_s32(uint32x4_t a, int32x4_t b, mve_pred16_t p) diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c index b13d851aec79b..5ddc3914f1857 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c @@ -1,14 +1,14 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include // CHECK-LABEL: @test_vminnmaq_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x half> @llvm.fabs.v8f16(<8 x half> [[A:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.fabs.v8f16(<8 x half> [[B:%.*]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x half> @llvm.minnum.v8f16(<8 x half> [[TMP0]], <8 x half> [[TMP1]]) +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x half> @llvm.fabs.v8f16(<8 x half> [[A:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x half> @llvm.fabs.v8f16(<8 x half> [[B:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x half> @llvm.minnum.v8f16(<8 x half> [[TMP0]], <8 x half> [[TMP1]]) // CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vminnmaq_f16(float16x8_t a, float16x8_t b) @@ -22,9 +22,9 @@ float16x8_t test_vminnmaq_f16(float16x8_t a, float16x8_t b) // CHECK-LABEL: @test_vminnmaq_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> [[A:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> [[B:%.*]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.minnum.v4f32(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.fabs.v4f32(<4 x float> [[A:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x float> @llvm.fabs.v4f32(<4 x float> [[B:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x float> @llvm.minnum.v4f32(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) // CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vminnmaq_f32(float32x4_t a, float32x4_t b) @@ -39,8 +39,8 @@ float32x4_t test_vminnmaq_f32(float32x4_t a, float32x4_t b) // CHECK-LABEL: @test_vminnmaq_m_f16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x half> @llvm.arm.mve.vminnma.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], <8 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x half> @llvm.arm.mve.vminnma.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], <8 x i1> [[TMP1]]) // CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vminnmaq_m_f16(float16x8_t a, float16x8_t b, mve_pred16_t p) @@ -55,8 +55,8 @@ float16x8_t test_vminnmaq_m_f16(float16x8_t a, float16x8_t b, mve_pred16_t p) // CHECK-LABEL: @test_vminnmaq_m_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.arm.mve.vminnma.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], <4 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x float> @llvm.arm.mve.vminnma.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], <4 x i1> [[TMP1]]) // CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vminnmaq_m_f32(float32x4_t a, float32x4_t b, mve_pred16_t p) diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c index 7ebcf45d88330..0723dfae2f064 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c @@ -1,12 +1,12 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include // CHECK-LABEL: @test_vminnmq_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x half> @llvm.minnum.v8f16(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x half> @llvm.minnum.v8f16(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]]) // CHECK-NEXT: ret <8 x half> [[TMP0]] // float16x8_t test_vminnmq_f16(float16x8_t a, float16x8_t b) @@ -20,7 +20,7 @@ float16x8_t test_vminnmq_f16(float16x8_t a, float16x8_t b) // CHECK-LABEL: @test_vminnmq_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.minnum.v4f32(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.minnum.v4f32(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]]) // CHECK-NEXT: ret <4 x float> [[TMP0]] // float32x4_t test_vminnmq_f32(float32x4_t a, float32x4_t b) @@ -35,8 +35,8 @@ float32x4_t test_vminnmq_f32(float32x4_t a, float32x4_t b) // CHECK-LABEL: @test_vminnmq_m_f16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x half> @llvm.arm.mve.min.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x half> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x half> @llvm.arm.mve.min.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x half> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vminnmq_m_f16(float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p) @@ -51,8 +51,8 @@ float16x8_t test_vminnmq_m_f16(float16x8_t inactive, float16x8_t a, float16x8_t // CHECK-LABEL: @test_vminnmq_m_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.arm.mve.min.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x float> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x float> @llvm.arm.mve.min.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x float> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vminnmq_m_f32(float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p) @@ -67,8 +67,8 @@ float32x4_t test_vminnmq_m_f32(float32x4_t inactive, float32x4_t a, float32x4_t // CHECK-LABEL: @test_vminnmq_x_f16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x half> @llvm.arm.mve.min.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x half> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x half> @llvm.arm.mve.min.predicated.v8f16.v8i1(<8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x half> undef) // CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vminnmq_x_f16(float16x8_t a, float16x8_t b, mve_pred16_t p) @@ -83,8 +83,8 @@ float16x8_t test_vminnmq_x_f16(float16x8_t a, float16x8_t b, mve_pred16_t p) // CHECK-LABEL: @test_vminnmq_x_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.arm.mve.min.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x float> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x float> @llvm.arm.mve.min.predicated.v4f32.v4i1(<4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x float> undef) // CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vminnmq_x_f32(float32x4_t a, float32x4_t b, mve_pred16_t p) diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminq.c index d4186858b121a..1f3b0d670ee17 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminq.c @@ -1,13 +1,13 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include // CHECK-LABEL: @test_vminq_u8( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = icmp ugt <16 x i8> [[A:%.*]], [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = select <16 x i1> [[TMP0]], <16 x i8> [[B]], <16 x i8> [[A]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp ule <16 x i8> [[A:%.*]], [[B:%.*]] +// CHECK-NEXT: [[TMP1:%.*]] = select <16 x i1> [[TMP0]], <16 x i8> [[A]], <16 x i8> [[B]] // CHECK-NEXT: ret <16 x i8> [[TMP1]] // uint8x16_t test_vminq_u8(uint8x16_t a, uint8x16_t b) @@ -21,8 +21,8 @@ uint8x16_t test_vminq_u8(uint8x16_t a, uint8x16_t b) // CHECK-LABEL: @test_vminq_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = icmp sgt <8 x i16> [[A:%.*]], [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = select <8 x i1> [[TMP0]], <8 x i16> [[B]], <8 x i16> [[A]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp sle <8 x i16> [[A:%.*]], [[B:%.*]] +// CHECK-NEXT: [[TMP1:%.*]] = select <8 x i1> [[TMP0]], <8 x i16> [[A]], <8 x i16> [[B]] // CHECK-NEXT: ret <8 x i16> [[TMP1]] // int16x8_t test_vminq_s16(int16x8_t a, int16x8_t b) @@ -36,8 +36,8 @@ int16x8_t test_vminq_s16(int16x8_t a, int16x8_t b) // CHECK-LABEL: @test_vminq_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = icmp ugt <4 x i32> [[A:%.*]], [[B:%.*]] -// CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[B]], <4 x i32> [[A]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]] +// CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[A]], <4 x i32> [[B]] // CHECK-NEXT: ret <4 x i32> [[TMP1]] // uint32x4_t test_vminq_u32(uint32x4_t a, uint32x4_t b) @@ -52,8 +52,8 @@ uint32x4_t test_vminq_u32(uint32x4_t a, uint32x4_t b) // CHECK-LABEL: @test_vminq_m_s8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.arm.mve.min.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 0, <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.min.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 0, <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <16 x i8> [[TMP2]] // int8x16_t test_vminq_m_s8(int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p) @@ -68,8 +68,8 @@ int8x16_t test_vminq_m_s8(int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred // CHECK-LABEL: @test_vminq_m_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.arm.mve.min.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], i32 1, <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.min.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], i32 1, <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <8 x i16> [[TMP2]] // uint16x8_t test_vminq_m_u16(uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p) @@ -84,8 +84,8 @@ uint16x8_t test_vminq_m_u16(uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve // CHECK-LABEL: @test_vminq_m_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.arm.mve.min.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.min.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]]) // CHECK-NEXT: ret <4 x i32> [[TMP2]] // int32x4_t test_vminq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p) @@ -100,8 +100,8 @@ int32x4_t test_vminq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pre // CHECK-LABEL: @test_vminq_x_u8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.arm.mve.min.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 1, <16 x i1> [[TMP1]], <16 x i8> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.min.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 1, <16 x i1> [[TMP1]], <16 x i8> undef) // CHECK-NEXT: ret <16 x i8> [[TMP2]] // uint8x16_t test_vminq_x_u8(uint8x16_t a, uint8x16_t b, mve_pred16_t p) @@ -116,8 +116,8 @@ uint8x16_t test_vminq_x_u8(uint8x16_t a, uint8x16_t b, mve_pred16_t p) // CHECK-LABEL: @test_vminq_x_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.arm.mve.min.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x i16> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.min.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], i32 0, <8 x i1> [[TMP1]], <8 x i16> undef) // CHECK-NEXT: ret <8 x i16> [[TMP2]] // int16x8_t test_vminq_x_s16(int16x8_t a, int16x8_t b, mve_pred16_t p) @@ -132,8 +132,8 @@ int16x8_t test_vminq_x_s16(int16x8_t a, int16x8_t b, mve_pred16_t p) // CHECK-LABEL: @test_vminq_x_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.arm.mve.min.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 1, <4 x i1> [[TMP1]], <4 x i32> undef) +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.min.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 1, <4 x i1> [[TMP1]], <4 x i32> undef) // CHECK-NEXT: ret <4 x i32> [[TMP2]] // uint32x4_t test_vminq_x_s32(uint32x4_t a, uint32x4_t b, mve_pred16_t p) diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c index f6b8b1be1e76b..cab424c3dbe17 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c @@ -6,7 +6,7 @@ #include -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N))); typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-call.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-call.c index 412923f1e898e..490ec92dfdeb5 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-call.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-call.c @@ -4,7 +4,7 @@ #include -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N))); typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c index 6c7edf9033f76..13d8f14f991a8 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c @@ -4,7 +4,7 @@ #include -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N))); typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c index d93be54a499cb..1a6a68a2e1f4f 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c @@ -3,7 +3,7 @@ #include -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N))); typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c index be0b314334b9d..d567c718000c8 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c @@ -5,7 +5,7 @@ #include -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N))); typedef svbfloat16_t fixed_bfloat16_t __attribute__((arm_sve_vector_bits(N))); diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-types.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-types.c index 625e096bf3d6f..a1cfc514081ea 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-types.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-types.c @@ -7,7 +7,7 @@ #include -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef svint8_t fixed_int8_t __attribute__((arm_sve_vector_bits(N))); typedef svint16_t fixed_int16_t __attribute__((arm_sve_vector_bits(N))); diff --git a/clang/test/CodeGen/avx2-builtins.c b/clang/test/CodeGen/avx2-builtins.c index 95659895eeaf9..f3de6d1b87474 100644 --- a/clang/test/CodeGen/avx2-builtins.c +++ b/clang/test/CodeGen/avx2-builtins.c @@ -8,25 +8,19 @@ __m256i test_mm256_abs_epi8(__m256i a) { // CHECK-LABEL: test_mm256_abs_epi8 - // CHECK: [[SUB:%.*]] = sub <32 x i8> zeroinitializer, %{{.*}} - // CHECK: [[CMP:%.*]] = icmp sgt <32 x i8> %{{.*}}, zeroinitializer - // CHECK: select <32 x i1> [[CMP]], <32 x i8> %{{.*}}, <32 x i8> [[SUB]] + // CHECK: [[ABS:%.*]] = call <32 x i8> @llvm.abs.v32i8(<32 x i8> %{{.*}}, i1 false) return _mm256_abs_epi8(a); } __m256i test_mm256_abs_epi16(__m256i a) { // CHECK-LABEL: test_mm256_abs_epi16 - // CHECK: [[SUB:%.*]] = sub <16 x i16> zeroinitializer, %{{.*}} - // CHECK: [[CMP:%.*]] = icmp sgt <16 x i16> %{{.*}}, zeroinitializer - // CHECK: select <16 x i1> [[CMP]], <16 x i16> %{{.*}}, <16 x i16> [[SUB]] + // CHECK: [[ABS:%.*]] = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %{{.*}}, i1 false) return _mm256_abs_epi16(a); } __m256i test_mm256_abs_epi32(__m256i a) { // CHECK-LABEL: test_mm256_abs_epi32 - // CHECK: [[SUB:%.*]] = sub <8 x i32> zeroinitializer, %{{.*}} - // CHECK: [[CMP:%.*]] = icmp sgt <8 x i32> %{{.*}}, zeroinitializer - // CHECK: select <8 x i1> [[CMP]], <8 x i32> %{{.*}}, <8 x i32> [[SUB]] + // CHECK: [[ABS:%.*]] = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %{{.*}}, i1 false) return _mm256_abs_epi32(a); } diff --git a/clang/test/CodeGen/avx512bw-builtins.c b/clang/test/CodeGen/avx512bw-builtins.c index c08b354d9519b..cc173f1a9cfe6 100644 --- a/clang/test/CodeGen/avx512bw-builtins.c +++ b/clang/test/CodeGen/avx512bw-builtins.c @@ -878,48 +878,36 @@ __m512i test_mm512_mask_blend_epi16(__mmask32 __U, __m512i __A, __m512i __W) { } __m512i test_mm512_abs_epi8(__m512i __A) { // CHECK-LABEL: @test_mm512_abs_epi8 - // CHECK: [[SUB:%.*]] = sub <64 x i8> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <64 x i8> [[A]], zeroinitializer - // CHECK: select <64 x i1> [[CMP]], <64 x i8> [[A]], <64 x i8> [[SUB]] + // CHECK: [[ABS:%.*]] = call <64 x i8> @llvm.abs.v64i8(<64 x i8> %{{.*}}, i1 false) return _mm512_abs_epi8(__A); } __m512i test_mm512_mask_abs_epi8(__m512i __W, __mmask64 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_abs_epi8 - // CHECK: [[SUB:%.*]] = sub <64 x i8> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <64 x i8> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <64 x i1> [[CMP]], <64 x i8> [[A]], <64 x i8> [[SUB]] - // CHECK: select <64 x i1> %{{.*}}, <64 x i8> [[SEL]], <64 x i8> %{{.*}} + // CHECK: [[ABS:%.*]] = call <64 x i8> @llvm.abs.v64i8(<64 x i8> %{{.*}}, i1 false) + // CHECK: select <64 x i1> %{{.*}}, <64 x i8> [[ABS]], <64 x i8> %{{.*}} return _mm512_mask_abs_epi8(__W,__U,__A); } __m512i test_mm512_maskz_abs_epi8(__mmask64 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_abs_epi8 - // CHECK: [[SUB:%.*]] = sub <64 x i8> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <64 x i8> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <64 x i1> [[CMP]], <64 x i8> [[A]], <64 x i8> [[SUB]] - // CHECK: select <64 x i1> %{{.*}}, <64 x i8> [[SEL]], <64 x i8> %{{.*}} + // CHECK: [[ABS:%.*]] = call <64 x i8> @llvm.abs.v64i8(<64 x i8> %{{.*}}, i1 false) + // CHECK: select <64 x i1> %{{.*}}, <64 x i8> [[ABS]], <64 x i8> %{{.*}} return _mm512_maskz_abs_epi8(__U,__A); } __m512i test_mm512_abs_epi16(__m512i __A) { // CHECK-LABEL: @test_mm512_abs_epi16 - // CHECK: [[SUB:%.*]] = sub <32 x i16> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <32 x i16> [[A]], zeroinitializer - // CHECK: select <32 x i1> [[CMP]], <32 x i16> [[A]], <32 x i16> [[SUB]] + // CHECK: [[ABS:%.*]] = call <32 x i16> @llvm.abs.v32i16(<32 x i16> %{{.*}}, i1 false) return _mm512_abs_epi16(__A); } __m512i test_mm512_mask_abs_epi16(__m512i __W, __mmask32 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_abs_epi16 - // CHECK: [[SUB:%.*]] = sub <32 x i16> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <32 x i16> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <32 x i1> [[CMP]], <32 x i16> [[A]], <32 x i16> [[SUB]] - // CHECK: select <32 x i1> %{{.*}}, <32 x i16> [[SEL]], <32 x i16> %{{.*}} + // CHECK: [[ABS:%.*]] = call <32 x i16> @llvm.abs.v32i16(<32 x i16> %{{.*}}, i1 false) + // CHECK: select <32 x i1> %{{.*}}, <32 x i16> [[ABS]], <32 x i16> %{{.*}} return _mm512_mask_abs_epi16(__W,__U,__A); } __m512i test_mm512_maskz_abs_epi16(__mmask32 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_abs_epi16 - // CHECK: [[SUB:%.*]] = sub <32 x i16> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <32 x i16> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <32 x i1> [[CMP]], <32 x i16> [[A]], <32 x i16> [[SUB]] - // CHECK: select <32 x i1> %{{.*}}, <32 x i16> [[SEL]], <32 x i16> %{{.*}} + // CHECK: [[ABS:%.*]] = call <32 x i16> @llvm.abs.v32i16(<32 x i16> %{{.*}}, i1 false) + // CHECK: select <32 x i1> %{{.*}}, <32 x i16> [[ABS]], <32 x i16> %{{.*}} return _mm512_maskz_abs_epi16(__U,__A); } __m512i test_mm512_packs_epi32(__m512i __A, __m512i __B) { diff --git a/clang/test/CodeGen/avx512f-builtins.c b/clang/test/CodeGen/avx512f-builtins.c index b01300c424b72..fb5db4c321748 100644 --- a/clang/test/CodeGen/avx512f-builtins.c +++ b/clang/test/CodeGen/avx512f-builtins.c @@ -10467,44 +10467,36 @@ __m512 test_mm512_set_ps (float __A, float __B, float __C, float __D, __m512i test_mm512_mask_abs_epi64 (__m512i __W, __mmask8 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_abs_epi64 - // CHECK: [[SUB:%.*]] = sub <8 x i64> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <8 x i64> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i64> [[A]], <8 x i64> [[SUB]] - // CHECK: select <8 x i1> %{{.*}}, <8 x i64> [[SEL]], <8 x i64> %{{.*}} + // CHECK: [[ABS:%.*]] = call <8 x i64> @llvm.abs.v8i64(<8 x i64> %{{.*}}, i1 false) + // CHECK: select <8 x i1> %{{.*}}, <8 x i64> [[ABS]], <8 x i64> %{{.*}} return _mm512_mask_abs_epi64 (__W,__U,__A); } __m512i test_mm512_maskz_abs_epi64 (__mmask8 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_abs_epi64 - // CHECK: [[SUB:%.*]] = sub <8 x i64> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <8 x i64> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i64> [[A]], <8 x i64> [[SUB]] - // CHECK: select <8 x i1> %{{.*}}, <8 x i64> [[SEL]], <8 x i64> %{{.*}} + // CHECK: [[ABS:%.*]] = call <8 x i64> @llvm.abs.v8i64(<8 x i64> %{{.*}}, i1 false) + // CHECK: select <8 x i1> %{{.*}}, <8 x i64> [[ABS]], <8 x i64> %{{.*}} return _mm512_maskz_abs_epi64 (__U,__A); } __m512i test_mm512_mask_abs_epi32 (__m512i __W, __mmask16 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_abs_epi32 - // CHECK: [[SUB:%.*]] = sub <16 x i32> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <16 x i32> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i32> [[A]], <16 x i32> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast <16 x i32> [[SEL]] to <8 x i64> - // CHECK: [[SEL:%.*]] = bitcast <8 x i64> [[TMP]] to <16 x i32> - // CHECK: select <16 x i1> %{{.*}}, <16 x i32> [[SEL]], <16 x i32> %{{.*}} + // CHECK: [[ABS:%.*]] = call <16 x i32> @llvm.abs.v16i32(<16 x i32> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <16 x i32> [[ABS]] to <8 x i64> + // CHECK: [[ABS:%.*]] = bitcast <8 x i64> [[TMP]] to <16 x i32> + // CHECK: select <16 x i1> %{{.*}}, <16 x i32> [[ABS]], <16 x i32> %{{.*}} return _mm512_mask_abs_epi32 (__W,__U,__A); } __m512i test_mm512_maskz_abs_epi32 (__mmask16 __U, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_abs_epi32 - // CHECK: [[SUB:%.*]] = sub <16 x i32> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <16 x i32> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i32> [[A]], <16 x i32> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast <16 x i32> [[SEL]] to <8 x i64> - // CHECK: [[SEL:%.*]] = bitcast <8 x i64> [[TMP]] to <16 x i32> - // CHECK: select <16 x i1> %{{.*}}, <16 x i32> [[SEL]], <16 x i32> %{{.*}} + // CHECK: [[ABS:%.*]] = call <16 x i32> @llvm.abs.v16i32(<16 x i32> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <16 x i32> [[ABS]] to <8 x i64> + // CHECK: [[ABS:%.*]] = bitcast <8 x i64> [[TMP]] to <16 x i32> + // CHECK: select <16 x i1> %{{.*}}, <16 x i32> [[ABS]], <16 x i32> %{{.*}} return _mm512_maskz_abs_epi32 (__U,__A); } diff --git a/clang/test/CodeGen/avx512vl-builtins.c b/clang/test/CodeGen/avx512vl-builtins.c index 3348e05790bcf..e7965119fb4b9 100644 --- a/clang/test/CodeGen/avx512vl-builtins.c +++ b/clang/test/CodeGen/avx512vl-builtins.c @@ -4537,90 +4537,68 @@ __m256 test_mm256_maskz_mul_ps(__mmask8 __U, __m256 __A, __m256 __B) { } __m128i test_mm_mask_abs_epi32(__m128i __W, __mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_mask_abs_epi32 - // CHECK: [[SUB:%.*]] = sub <4 x i32> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <4 x i32> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[A]], <4 x i32> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast <4 x i32> [[SEL]] to <2 x i64> - // CHECK: [[SEL:%.*]] = bitcast <2 x i64> [[TMP]] to <4 x i32> - // CHECK: select <4 x i1> %{{.*}}, <4 x i32> [[SEL]], <4 x i32> %{{.*}} + // CHECK: [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <4 x i32> [[ABS]] to <2 x i64> + // CHECK: [[ABS:%.*]] = bitcast <2 x i64> [[TMP]] to <4 x i32> + // CHECK: select <4 x i1> %{{.*}}, <4 x i32> [[ABS]], <4 x i32> %{{.*}} return _mm_mask_abs_epi32(__W,__U,__A); } __m128i test_mm_maskz_abs_epi32(__mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_maskz_abs_epi32 - // CHECK: [[SUB:%.*]] = sub <4 x i32> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <4 x i32> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[A]], <4 x i32> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast <4 x i32> [[SEL]] to <2 x i64> - // CHECK: [[SEL:%.*]] = bitcast <2 x i64> [[TMP]] to <4 x i32> - // CHECK: select <4 x i1> %{{.*}}, <4 x i32> [[SEL]], <4 x i32> %{{.*}} + // CHECK: [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <4 x i32> [[ABS]] to <2 x i64> + // CHECK: [[ABS:%.*]] = bitcast <2 x i64> [[TMP]] to <4 x i32> + // CHECK: select <4 x i1> %{{.*}}, <4 x i32> [[ABS]], <4 x i32> %{{.*}} return _mm_maskz_abs_epi32(__U,__A); } __m256i test_mm256_mask_abs_epi32(__m256i __W, __mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_abs_epi32 - // CHECK: [[SUB:%.*]] = sub <8 x i32> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <8 x i32> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i32> [[A]], <8 x i32> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast <8 x i32> [[SEL]] to <4 x i64> - // CHECK: [[SEL:%.*]] = bitcast <4 x i64> [[TMP]] to <8 x i32> - // CHECK: select <8 x i1> %{{.*}}, <8 x i32> [[SEL]], <8 x i32> %{{.*}} + // CHECK: [[ABS:%.*]] = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <8 x i32> [[ABS]] to <4 x i64> + // CHECK: [[ABS:%.*]] = bitcast <4 x i64> [[TMP]] to <8 x i32> + // CHECK: select <8 x i1> %{{.*}}, <8 x i32> [[ABS]], <8 x i32> %{{.*}} return _mm256_mask_abs_epi32(__W,__U,__A); } __m256i test_mm256_maskz_abs_epi32(__mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_abs_epi32 - // CHECK: [[SUB:%.*]] = sub <8 x i32> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <8 x i32> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i32> [[A]], <8 x i32> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast <8 x i32> [[SEL]] to <4 x i64> - // CHECK: [[SEL:%.*]] = bitcast <4 x i64> [[TMP]] to <8 x i32> - // CHECK: select <8 x i1> %{{.*}}, <8 x i32> [[SEL]], <8 x i32> %{{.*}} + // CHECK: [[ABS:%.*]] = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <8 x i32> [[ABS]] to <4 x i64> + // CHECK: [[ABS:%.*]] = bitcast <4 x i64> [[TMP]] to <8 x i32> + // CHECK: select <8 x i1> %{{.*}}, <8 x i32> [[ABS]], <8 x i32> %{{.*}} return _mm256_maskz_abs_epi32(__U,__A); } __m128i test_mm_abs_epi64(__m128i __A) { // CHECK-LABEL: @test_mm_abs_epi64 - // CHECK: [[SUB:%.*]] = sub <2 x i64> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <2 x i64> [[A]], zeroinitializer - // CHECK: select <2 x i1> [[CMP]], <2 x i64> [[A]], <2 x i64> [[SUB]] - + // CHECK: [[ABS:%.*]] = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %{{.*}}, i1 false) return _mm_abs_epi64(__A); } __m128i test_mm_mask_abs_epi64(__m128i __W, __mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_mask_abs_epi64 - // CHECK: [[SUB:%.*]] = sub <2 x i64> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <2 x i64> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i64> [[A]], <2 x i64> [[SUB]] - // CHECK: select <2 x i1> %{{.*}}, <2 x i64> [[SEL]], <2 x i64> %{{.*}} - + // CHECK: [[ABS:%.*]] = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %{{.*}}, i1 false) + // CHECK: select <2 x i1> %{{.*}}, <2 x i64> [[ABS]], <2 x i64> %{{.*}} return _mm_mask_abs_epi64(__W,__U,__A); } __m128i test_mm_maskz_abs_epi64(__mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_maskz_abs_epi64 - // CHECK: [[SUB:%.*]] = sub <2 x i64> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <2 x i64> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i64> [[A]], <2 x i64> [[SUB]] - // CHECK: select <2 x i1> %{{.*}}, <2 x i64> [[SEL]], <2 x i64> %{{.*}} + // CHECK: [[ABS:%.*]] = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %{{.*}}, i1 false) + // CHECK: select <2 x i1> %{{.*}}, <2 x i64> [[ABS]], <2 x i64> %{{.*}} return _mm_maskz_abs_epi64(__U,__A); } __m256i test_mm256_abs_epi64(__m256i __A) { // CHECK-LABEL: @test_mm256_abs_epi64 - // CHECK: [[SUB:%.*]] = sub <4 x i64> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <4 x i64> [[A]], zeroinitializer - // CHECK: select <4 x i1> [[CMP]], <4 x i64> [[A]], <4 x i64> [[SUB]] + // CHECK: [[ABS:%.*]] = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %{{.*}}, i1 false) return _mm256_abs_epi64(__A); } __m256i test_mm256_mask_abs_epi64(__m256i __W, __mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_abs_epi64 - // CHECK: [[SUB:%.*]] = sub <4 x i64> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <4 x i64> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i64> [[A]], <4 x i64> [[SUB]] - // CHECK: select <4 x i1> %{{.*}}, <4 x i64> [[SEL]], <4 x i64> %{{.*}} + // CHECK: [[ABS:%.*]] = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %{{.*}}, i1 false) + // CHECK: select <4 x i1> %{{.*}}, <4 x i64> [[ABS]], <4 x i64> %{{.*}} return _mm256_mask_abs_epi64(__W,__U,__A); } __m256i test_mm256_maskz_abs_epi64(__mmask8 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_abs_epi64 - // CHECK: [[SUB:%.*]] = sub <4 x i64> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <4 x i64> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i64> [[A]], <4 x i64> [[SUB]] - // CHECK: select <4 x i1> %{{.*}}, <4 x i64> [[SEL]], <4 x i64> %{{.*}} + // CHECK: [[ABS:%.*]] = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %{{.*}}, i1 false) + // CHECK: select <4 x i1> %{{.*}}, <4 x i64> [[ABS]], <4 x i64> %{{.*}} return _mm256_maskz_abs_epi64(__U,__A); } __m128i test_mm_maskz_max_epi32(__mmask8 __M, __m128i __A, __m128i __B) { diff --git a/clang/test/CodeGen/avx512vlbw-builtins.c b/clang/test/CodeGen/avx512vlbw-builtins.c index 0cbd8a1a595fb..df2adfdb97be6 100644 --- a/clang/test/CodeGen/avx512vlbw-builtins.c +++ b/clang/test/CodeGen/avx512vlbw-builtins.c @@ -897,89 +897,73 @@ __m256i test_mm256_mask_blend_epi16(__mmask16 __U, __m256i __A, __m256i __W) { __m128i test_mm_mask_abs_epi8(__m128i __W, __mmask16 __U, __m128i __A) { // CHECK-LABEL: @test_mm_mask_abs_epi8 - // CHECK: [[SUB:%.*]] = sub <16 x i8> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <16 x i8> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i8> [[A]], <16 x i8> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast [[SRCTY:<16 x i8>]] [[SEL]] to [[DSTTY:<2 x i64>]] - // CHECK: [[SEL:%.*]] = bitcast [[DSTTY]] [[TMP]] to [[SRCTY]] - // CHECK: select <16 x i1> %{{.*}}, <16 x i8> [[SEL]], <16 x i8> %{{.*}} + // CHECK: [[ABS:%.*]] = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <16 x i8> [[ABS]] to <2 x i64> + // CHECK: [[ABS:%.*]] = bitcast <2 x i64> [[TMP]] to <16 x i8> + // CHECK: select <16 x i1> %{{.*}}, <16 x i8> [[ABS]], <16 x i8> %{{.*}} return _mm_mask_abs_epi8(__W,__U,__A); } __m128i test_mm_maskz_abs_epi8(__mmask16 __U, __m128i __A) { // CHECK-LABEL: @test_mm_maskz_abs_epi8 - // CHECK: [[SUB:%.*]] = sub <16 x i8> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <16 x i8> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i8> [[A]], <16 x i8> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast [[SRCTY:<16 x i8>]] [[SEL]] to [[DSTTY:<2 x i64>]] - // CHECK: [[SEL:%.*]] = bitcast [[DSTTY]] [[TMP]] to [[SRCTY]] - // CHECK: select <16 x i1> %{{.*}}, <16 x i8> [[SEL]], <16 x i8> %{{.*}} + // CHECK: [[ABS:%.*]] = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <16 x i8> [[ABS]] to <2 x i64> + // CHECK: [[ABS:%.*]] = bitcast <2 x i64> [[TMP]] to <16 x i8> + // CHECK: select <16 x i1> %{{.*}}, <16 x i8> [[ABS]], <16 x i8> %{{.*}} return _mm_maskz_abs_epi8(__U,__A); } __m256i test_mm256_mask_abs_epi8(__m256i __W, __mmask32 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_abs_epi8 - // CHECK: [[SUB:%.*]] = sub <32 x i8> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <32 x i8> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <32 x i1> [[CMP]], <32 x i8> [[A]], <32 x i8> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast [[SRCTY:<32 x i8>]] [[SEL]] to [[DSTTY:<4 x i64>]] - // CHECK: [[SEL:%.*]] = bitcast [[DSTTY]] [[TMP]] to [[SRCTY]] - // CHECK: select <32 x i1> %{{.*}}, <32 x i8> [[SEL]], <32 x i8> %{{.*}} + // CHECK: [[ABS:%.*]] = call <32 x i8> @llvm.abs.v32i8(<32 x i8> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <32 x i8> [[ABS]] to <4 x i64> + // CHECK: [[ABS:%.*]] = bitcast <4 x i64> [[TMP]] to <32 x i8> + // CHECK: select <32 x i1> %{{.*}}, <32 x i8> [[ABS]], <32 x i8> %{{.*}} return _mm256_mask_abs_epi8(__W,__U,__A); } __m256i test_mm256_maskz_abs_epi8(__mmask32 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_abs_epi8 - // CHECK: [[SUB:%.*]] = sub <32 x i8> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <32 x i8> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <32 x i1> [[CMP]], <32 x i8> [[A]], <32 x i8> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast [[SRCTY:<32 x i8>]] [[SEL]] to [[DSTTY:<4 x i64>]] - // CHECK: [[SEL:%.*]] = bitcast [[DSTTY]] [[TMP]] to [[SRCTY]] - // CHECK: select <32 x i1> %{{.*}}, <32 x i8> [[SEL]], <32 x i8> %{{.*}} + // CHECK: [[ABS:%.*]] = call <32 x i8> @llvm.abs.v32i8(<32 x i8> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <32 x i8> [[ABS]] to <4 x i64> + // CHECK: [[ABS:%.*]] = bitcast <4 x i64> [[TMP]] to <32 x i8> + // CHECK: select <32 x i1> %{{.*}}, <32 x i8> [[ABS]], <32 x i8> %{{.*}} return _mm256_maskz_abs_epi8(__U,__A); } __m128i test_mm_mask_abs_epi16(__m128i __W, __mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_mask_abs_epi16 - // CHECK: [[SUB:%.*]] = sub <8 x i16> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <8 x i16> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i16> [[A]], <8 x i16> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast [[SRCTY:<8 x i16>]] [[SEL]] to [[DSTTY:<2 x i64>]] - // CHECK: [[SEL:%.*]] = bitcast [[DSTTY]] [[TMP]] to [[SRCTY]] - // CHECK: select <8 x i1> %{{.*}}, <8 x i16> [[SEL]], <8 x i16> %{{.*}} + // CHECK: [[ABS:%.*]] = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <8 x i16> [[ABS]] to <2 x i64> + // CHECK: [[ABS:%.*]] = bitcast <2 x i64> [[TMP]] to <8 x i16> + // CHECK: select <8 x i1> %{{.*}}, <8 x i16> [[ABS]], <8 x i16> %{{.*}} return _mm_mask_abs_epi16(__W,__U,__A); } __m128i test_mm_maskz_abs_epi16(__mmask8 __U, __m128i __A) { // CHECK-LABEL: @test_mm_maskz_abs_epi16 - // CHECK: [[SUB:%.*]] = sub <8 x i16> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <8 x i16> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i16> [[A]], <8 x i16> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast [[SRCTY:<8 x i16>]] [[SEL]] to [[DSTTY:<2 x i64>]] - // CHECK: [[SEL:%.*]] = bitcast [[DSTTY]] [[TMP]] to [[SRCTY]] - // CHECK: select <8 x i1> %{{.*}}, <8 x i16> [[SEL]], <8 x i16> %{{.*}} + // CHECK: [[ABS:%.*]] = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <8 x i16> [[ABS]] to <2 x i64> + // CHECK: [[ABS:%.*]] = bitcast <2 x i64> [[TMP]] to <8 x i16> + // CHECK: select <8 x i1> %{{.*}}, <8 x i16> [[ABS]], <8 x i16> %{{.*}} return _mm_maskz_abs_epi16(__U,__A); } __m256i test_mm256_mask_abs_epi16(__m256i __W, __mmask16 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_abs_epi16 - // CHECK: [[SUB:%.*]] = sub <16 x i16> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <16 x i16> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i16> [[A]], <16 x i16> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast [[SRCTY:<16 x i16>]] [[SEL]] to [[DSTTY:<4 x i64>]] - // CHECK: [[SEL:%.*]] = bitcast [[DSTTY]] [[TMP]] to [[SRCTY]] - // CHECK: select <16 x i1> %{{.*}}, <16 x i16> [[SEL]], <16 x i16> %{{.*}} + // CHECK: [[ABS:%.*]] = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <16 x i16> [[ABS]] to <4 x i64> + // CHECK: [[ABS:%.*]] = bitcast <4 x i64> [[TMP]] to <16 x i16> + // CHECK: select <16 x i1> %{{.*}}, <16 x i16> [[ABS]], <16 x i16> %{{.*}} return _mm256_mask_abs_epi16(__W,__U,__A); } __m256i test_mm256_maskz_abs_epi16(__mmask16 __U, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_abs_epi16 - // CHECK: [[SUB:%.*]] = sub <16 x i16> zeroinitializer, [[A:%.*]] - // CHECK: [[CMP:%.*]] = icmp sgt <16 x i16> [[A]], zeroinitializer - // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i16> [[A]], <16 x i16> [[SUB]] - // CHECK: [[TMP:%.*]] = bitcast [[SRCTY:<16 x i16>]] [[SEL]] to [[DSTTY:<4 x i64>]] - // CHECK: [[SEL:%.*]] = bitcast [[DSTTY]] [[TMP]] to [[SRCTY]] - // CHECK: select <16 x i1> %{{.*}}, <16 x i16> [[SEL]], <16 x i16> %{{.*}} + // CHECK: [[ABS:%.*]] = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %{{.*}}, i1 false) + // CHECK: [[TMP:%.*]] = bitcast <16 x i16> [[ABS]] to <4 x i64> + // CHECK: [[ABS:%.*]] = bitcast <4 x i64> [[TMP]] to <16 x i16> + // CHECK: select <16 x i1> %{{.*}}, <16 x i16> [[ABS]], <16 x i16> %{{.*}} return _mm256_maskz_abs_epi16(__U,__A); } diff --git a/clang/test/CodeGen/builtins-ppc-altivec.c b/clang/test/CodeGen/builtins-ppc-altivec.c index d53011b37d413..06f70a9019039 100644 --- a/clang/test/CodeGen/builtins-ppc-altivec.c +++ b/clang/test/CodeGen/builtins-ppc-altivec.c @@ -38,6 +38,13 @@ vector float res_vf; // CHECK-NOALTIVEC: error: unknown type name 'vector' // CHECK-NOALTIVEC-NOT: '(error)' +const signed char *param_sc_ld; +const unsigned char *param_uc_ld; +const short *param_s_ld; +const unsigned short *param_us_ld; +const int *param_i_ld; +const unsigned int *param_ui_ld; +const float *param_f_ld; signed char param_sc; unsigned char param_uc; @@ -1029,6 +1036,85 @@ void test2() { // CHECK: @llvm.ppc.altivec.vcmpeqfp // CHECK-LE: @llvm.ppc.altivec.vcmpeqfp + /* vec_cmpne */ + res_vbc = vec_cmpne(vsc, vsc); +// CHECK: @llvm.ppc.altivec.vcmpequb +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequb +// CHECK-LE: xor + + res_vbc = vec_cmpne(vuc, vuc); +// CHECK: @llvm.ppc.altivec.vcmpequb +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequb +// CHECK-LE: xor + + res_vbc = vec_cmpne(vbc, vbc); +// CHECK: @llvm.ppc.altivec.vcmpequb +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequb +// CHECK-LE: xor + + res_vbc = vec_cmpne(vbc, vbc); +// CHECK: @llvm.ppc.altivec.vcmpequb +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequb +// CHECK-LE: xor + + res_vbs = vec_cmpne(vs, vs); +// CHECK: @llvm.ppc.altivec.vcmpequh +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequh +// CHECK-LE: xor + + res_vbs = vec_cmpne(vus, vus); +// CHECK: @llvm.ppc.altivec.vcmpequh +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequh +// CHECK-LE: xor + + res_vbs = vec_cmpne(vbs, vbs); +// CHECK: @llvm.ppc.altivec.vcmpequh +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequh +// CHECK-LE: xor + + res_vbs = vec_cmpne(vbs, vbs); +// CHECK: @llvm.ppc.altivec.vcmpequh +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequh +// CHECK-LE: xor + + res_vbi = vec_cmpne(vi, vi); +// CHECK: @llvm.ppc.altivec.vcmpequw +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequw +// CHECK-LE: xor + + res_vbi = vec_cmpne(vui, vui); +// CHECK: @llvm.ppc.altivec.vcmpequw +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequw +// CHECK-LE: xor + + res_vbi = vec_cmpne(vbi, vbi); +// CHECK: @llvm.ppc.altivec.vcmpequw +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequw +// CHECK-LE: xor + + res_vbi = vec_cmpne(vbi, vbi); +// CHECK: @llvm.ppc.altivec.vcmpequw +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpequw +// CHECK-LE: xor + + res_vbi = vec_cmpne(vf, vf); +// CHECK: @llvm.ppc.altivec.vcmpeqfp +// CHECK: xor +// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp +// CHECK-LE: xor + /* vec_cmpge */ res_vbc = vec_cmpge(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb @@ -1313,7 +1399,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vsc = vec_ld(0, ¶m_sc); + res_vsc = vec_ld(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1321,7 +1407,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vuc = vec_ld(0, ¶m_uc); + res_vuc = vec_ld(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1333,7 +1419,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vs = vec_ld(0, ¶m_s); + res_vs = vec_ld(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1341,7 +1427,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vus = vec_ld(0, ¶m_us); + res_vus = vec_ld(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1357,7 +1443,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vi = vec_ld(0, ¶m_i); + res_vi = vec_ld(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1365,7 +1451,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vui = vec_ld(0, ¶m_ui); + res_vui = vec_ld(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1377,7 +1463,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vf = vec_ld(0, ¶m_f); + res_vf = vec_ld(0, param_f_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1385,7 +1471,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vsc = vec_lvx(0, ¶m_sc); + res_vsc = vec_lvx(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1393,7 +1479,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vuc = vec_lvx(0, ¶m_uc); + res_vuc = vec_lvx(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1405,7 +1491,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vs = vec_lvx(0, ¶m_s); + res_vs = vec_lvx(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1413,7 +1499,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vus = vec_lvx(0, ¶m_us); + res_vus = vec_lvx(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1429,7 +1515,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vi = vec_lvx(0, ¶m_i); + res_vi = vec_lvx(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1437,7 +1523,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vui = vec_lvx(0, ¶m_ui); + res_vui = vec_lvx(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx @@ -1449,64 +1535,64 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx - res_vf = vec_lvx(0, ¶m_f); + res_vf = vec_lvx(0, param_f_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK-LE: @llvm.ppc.altivec.lvx /* vec_lde */ - res_vsc = vec_lde(0, ¶m_sc); + res_vsc = vec_lde(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvebx // CHECK-LE: @llvm.ppc.altivec.lvebx - res_vuc = vec_lde(0, ¶m_uc); + res_vuc = vec_lde(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvebx // CHECK-LE: @llvm.ppc.altivec.lvebx - res_vs = vec_lde(0, ¶m_s); + res_vs = vec_lde(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvehx // CHECK-LE: @llvm.ppc.altivec.lvehx - res_vus = vec_lde(0, ¶m_us); + res_vus = vec_lde(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvehx // CHECK-LE: @llvm.ppc.altivec.lvehx - res_vi = vec_lde(0, ¶m_i); + res_vi = vec_lde(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvewx // CHECK-LE: @llvm.ppc.altivec.lvewx - res_vui = vec_lde(0, ¶m_ui); + res_vui = vec_lde(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvewx // CHECK-LE: @llvm.ppc.altivec.lvewx - res_vf = vec_lde(0, ¶m_f); + res_vf = vec_lde(0, param_f_ld); // CHECK: @llvm.ppc.altivec.lvewx // CHECK-LE: @llvm.ppc.altivec.lvewx - res_vsc = vec_lvebx(0, ¶m_sc); + res_vsc = vec_lvebx(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvebx // CHECK-LE: @llvm.ppc.altivec.lvebx - res_vuc = vec_lvebx(0, ¶m_uc); + res_vuc = vec_lvebx(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvebx // CHECK-LE: @llvm.ppc.altivec.lvebx - res_vs = vec_lvehx(0, ¶m_s); + res_vs = vec_lvehx(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvehx // CHECK-LE: @llvm.ppc.altivec.lvehx - res_vus = vec_lvehx(0, ¶m_us); + res_vus = vec_lvehx(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvehx // CHECK-LE: @llvm.ppc.altivec.lvehx - res_vi = vec_lvewx(0, ¶m_i); + res_vi = vec_lvewx(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvewx // CHECK-LE: @llvm.ppc.altivec.lvewx - res_vui = vec_lvewx(0, ¶m_ui); + res_vui = vec_lvewx(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvewx // CHECK-LE: @llvm.ppc.altivec.lvewx - res_vf = vec_lvewx(0, ¶m_f); + res_vf = vec_lvewx(0, param_f_ld); // CHECK: @llvm.ppc.altivec.lvewx // CHECK-LE: @llvm.ppc.altivec.lvewx @@ -1515,7 +1601,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vsc = vec_ldl(0, ¶m_sc); + res_vsc = vec_ldl(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1523,7 +1609,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vuc = vec_ldl(0, ¶m_uc); + res_vuc = vec_ldl(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1535,7 +1621,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vs = vec_ldl(0, ¶m_s); + res_vs = vec_ldl(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1543,7 +1629,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vus = vec_ldl(0, ¶m_us); + res_vus = vec_ldl(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1559,7 +1645,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vi = vec_ldl(0, ¶m_i); + res_vi = vec_ldl(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1567,7 +1653,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vui = vec_ldl(0, ¶m_ui); + res_vui = vec_ldl(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1579,7 +1665,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vf = vec_ldl(0, ¶m_f); + res_vf = vec_ldl(0, param_f_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1587,7 +1673,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vsc = vec_lvxl(0, ¶m_sc); + res_vsc = vec_lvxl(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1599,7 +1685,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vuc = vec_lvxl(0, ¶m_uc); + res_vuc = vec_lvxl(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1607,7 +1693,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vs = vec_lvxl(0, ¶m_s); + res_vs = vec_lvxl(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1615,7 +1701,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vus = vec_lvxl(0, ¶m_us); + res_vus = vec_lvxl(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1631,7 +1717,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vi = vec_lvxl(0, ¶m_i); + res_vi = vec_lvxl(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1639,7 +1725,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vui = vec_lvxl(0, ¶m_ui); + res_vui = vec_lvxl(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1651,7 +1737,7 @@ void test6() { // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl - res_vf = vec_lvxl(0, ¶m_f); + res_vf = vec_lvxl(0, param_f_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK-LE: @llvm.ppc.altivec.lvxl @@ -1665,12 +1751,12 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.vlogefp /* vec_lvsl */ - res_vuc = vec_lvsl(0, ¶m_i); + res_vuc = vec_lvsl(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.lvsl /* vec_lvsr */ - res_vuc = vec_lvsr(0, ¶m_i); + res_vuc = vec_lvsr(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvsr // CHECK-LE: @llvm.ppc.altivec.lvsr @@ -6029,7 +6115,7 @@ void test6() { // CHECK-LE: insertelement <4 x float> /* vec_lvlx */ - res_vsc = vec_lvlx(0, ¶m_sc); + res_vsc = vec_lvlx(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <16 x i8> zeroinitializer @@ -6049,7 +6135,7 @@ void test6() { // CHECK-LE: store <16 x i8> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vuc = vec_lvlx(0, ¶m_uc); + res_vuc = vec_lvlx(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <16 x i8> zeroinitializer @@ -6079,7 +6165,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.vperm - res_vs = vec_lvlx(0, ¶m_s); + res_vs = vec_lvlx(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <8 x i16> zeroinitializer @@ -6099,7 +6185,7 @@ void test6() { // CHECK-LE: store <8 x i16> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vus = vec_lvlx(0, ¶m_us); + res_vus = vec_lvlx(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <8 x i16> zeroinitializer @@ -6139,7 +6225,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.vperm - res_vi = vec_lvlx(0, ¶m_i); + res_vi = vec_lvlx(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <4 x i32> zeroinitializer @@ -6159,7 +6245,7 @@ void test6() { // CHECK-LE: store <4 x i32> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vui = vec_lvlx(0, ¶m_ui); + res_vui = vec_lvlx(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <4 x i32> zeroinitializer @@ -6200,7 +6286,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.vperm /* vec_lvlxl */ - res_vsc = vec_lvlxl(0, ¶m_sc); + res_vsc = vec_lvlxl(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <16 x i8> zeroinitializer @@ -6220,7 +6306,7 @@ void test6() { // CHECK-LE: store <16 x i8> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vuc = vec_lvlxl(0, ¶m_uc); + res_vuc = vec_lvlxl(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <16 x i8> zeroinitializer @@ -6250,7 +6336,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.vperm - res_vs = vec_lvlxl(0, ¶m_s); + res_vs = vec_lvlxl(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <8 x i16> zeroinitializer @@ -6270,7 +6356,7 @@ void test6() { // CHECK-LE: store <8 x i16> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vus = vec_lvlxl(0, ¶m_us); + res_vus = vec_lvlxl(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <8 x i16> zeroinitializer @@ -6310,7 +6396,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.vperm - res_vi = vec_lvlxl(0, ¶m_i); + res_vi = vec_lvlxl(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <4 x i32> zeroinitializer @@ -6330,7 +6416,7 @@ void test6() { // CHECK-LE: store <4 x i32> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vui = vec_lvlxl(0, ¶m_ui); + res_vui = vec_lvlxl(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <4 x i32> zeroinitializer @@ -6371,7 +6457,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.vperm /* vec_lvrx */ - res_vsc = vec_lvrx(0, ¶m_sc); + res_vsc = vec_lvrx(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <16 x i8> zeroinitializer @@ -6391,7 +6477,7 @@ void test6() { // CHECK-LE: store <16 x i8> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vuc = vec_lvrx(0, ¶m_uc); + res_vuc = vec_lvrx(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <16 x i8> zeroinitializer @@ -6421,7 +6507,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.vperm - res_vs = vec_lvrx(0, ¶m_s); + res_vs = vec_lvrx(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <8 x i16> zeroinitializer @@ -6441,7 +6527,7 @@ void test6() { // CHECK-LE: store <8 x i16> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vus = vec_lvrx(0, ¶m_us); + res_vus = vec_lvrx(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <8 x i16> zeroinitializer @@ -6481,7 +6567,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.vperm - res_vi = vec_lvrx(0, ¶m_i); + res_vi = vec_lvrx(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <4 x i32> zeroinitializer @@ -6501,7 +6587,7 @@ void test6() { // CHECK-LE: store <4 x i32> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vui = vec_lvrx(0, ¶m_ui); + res_vui = vec_lvrx(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvx // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <4 x i32> zeroinitializer @@ -6542,7 +6628,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.vperm /* vec_lvrxl */ - res_vsc = vec_lvrxl(0, ¶m_sc); + res_vsc = vec_lvrxl(0, param_sc_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <16 x i8> zeroinitializer @@ -6562,7 +6648,7 @@ void test6() { // CHECK-LE: store <16 x i8> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vuc = vec_lvrxl(0, ¶m_uc); + res_vuc = vec_lvrxl(0, param_uc_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <16 x i8> zeroinitializer @@ -6592,7 +6678,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.vperm - res_vs = vec_lvrxl(0, ¶m_s); + res_vs = vec_lvrxl(0, param_s_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <8 x i16> zeroinitializer @@ -6612,7 +6698,7 @@ void test6() { // CHECK-LE: store <8 x i16> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vus = vec_lvrxl(0, ¶m_us); + res_vus = vec_lvrxl(0, param_us_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <8 x i16> zeroinitializer @@ -6652,7 +6738,7 @@ void test6() { // CHECK-LE: @llvm.ppc.altivec.lvsl // CHECK-LE: @llvm.ppc.altivec.vperm - res_vi = vec_lvrxl(0, ¶m_i); + res_vi = vec_lvrxl(0, param_i_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <4 x i32> zeroinitializer @@ -6672,7 +6758,7 @@ void test6() { // CHECK-LE: store <4 x i32> zeroinitializer // CHECK-LE: @llvm.ppc.altivec.vperm - res_vui = vec_lvrxl(0, ¶m_ui); + res_vui = vec_lvrxl(0, param_ui_ld); // CHECK: @llvm.ppc.altivec.lvxl // CHECK: @llvm.ppc.altivec.lvsl // CHECK: store <4 x i32> zeroinitializer @@ -9354,31 +9440,31 @@ void test8() { void test9() { // CHECK-LABEL: define void @test9 // CHECK-LE-LABEL: define void @test9 - res_vsc = vec_xl(param_sll, ¶m_sc); + res_vsc = vec_xl(param_sll, param_sc_ld); // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1 // CHECK-LE: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1 - res_vuc = vec_xl(param_sll, ¶m_uc); + res_vuc = vec_xl(param_sll, param_uc_ld); // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1 // CHECK-LE: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1 - res_vs = vec_xl(param_sll, ¶m_s); + res_vs = vec_xl(param_sll, param_s_ld); // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1 // CHECK-LE: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1 - res_vus = vec_xl(param_sll, ¶m_us); + res_vus = vec_xl(param_sll, param_us_ld); // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1 // CHECK-LE: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1 - res_vi = vec_xl(param_sll, ¶m_i); + res_vi = vec_xl(param_sll, param_i_ld); // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1 // CHECK-LE: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1 - res_vui = vec_xl(param_sll, ¶m_ui); + res_vui = vec_xl(param_sll, param_ui_ld); // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1 // CHECK-LE: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1 - res_vf = vec_xl(param_sll, ¶m_f); + res_vf = vec_xl(param_sll, param_f_ld); // CHECK: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 1 // CHECK-LE: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 1 } @@ -9420,35 +9506,35 @@ void test10() { void test11() { // CHECK-LABEL: define void @test11 // CHECK-LE-LABEL: define void @test11 - res_vsc = vec_xl_be(param_sll, ¶m_sc); + res_vsc = vec_xl_be(param_sll, param_sc_ld); // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1 // CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}}) // CHECK-LE: shufflevector <16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}}, <16 x i32> - res_vuc = vec_xl_be(param_sll, ¶m_uc); + res_vuc = vec_xl_be(param_sll, param_uc_ld); // CHECK: load <16 x i8>, <16 x i8>* %{{[0-9]+}}, align 1 // CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}}) // CHECK-LE: shufflevector <16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}}, <16 x i32> - res_vs = vec_xl_be(param_sll, ¶m_s); + res_vs = vec_xl_be(param_sll, param_s_ld); // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1 // CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}}) // CHECK-LE: shufflevector <8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}}, <8 x i32> - res_vus = vec_xl_be(param_sll, ¶m_us); + res_vus = vec_xl_be(param_sll, param_us_ld); // CHECK: load <8 x i16>, <8 x i16>* %{{[0-9]+}}, align 1 // CHECK-LE: call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %{{[0-9]+}}) // CHECK-LE: shufflevector <8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}}, <8 x i32> - res_vi = vec_xl_be(param_sll, ¶m_i); + res_vi = vec_xl_be(param_sll, param_i_ld); // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1 // CHECK-LE: call <4 x i32> @llvm.ppc.vsx.lxvw4x.be(i8* %{{[0-9]+}}) - res_vui = vec_xl_be(param_sll, ¶m_ui); + res_vui = vec_xl_be(param_sll, param_ui_ld); // CHECK: load <4 x i32>, <4 x i32>* %{{[0-9]+}}, align 1 // CHECK-LE: call <4 x i32> @llvm.ppc.vsx.lxvw4x.be(i8* %{{[0-9]+}}) - res_vf = vec_xl_be(param_sll, ¶m_f); + res_vf = vec_xl_be(param_sll, param_f_ld); // CHECK: load <4 x float>, <4 x float>* %{{[0-9]+}}, align 1 // CHECK-LE: call <4 x i32> @llvm.ppc.vsx.lxvw4x.be(i8* %{{[0-9]+}}) } diff --git a/clang/test/CodeGen/builtins-ppc-p10vector.c b/clang/test/CodeGen/builtins-ppc-p10vector.c index 6fe6d9fdf72d6..ad63d646196c3 100644 --- a/clang/test/CodeGen/builtins-ppc-p10vector.c +++ b/clang/test/CodeGen/builtins-ppc-p10vector.c @@ -23,11 +23,15 @@ vector double vda, vdb; signed int *iap; unsigned int uia, uib, *uiap; signed char *cap; -unsigned char uca, *ucap; -signed short *sap; -unsigned short usa, *usap; -signed long long *llap, llb; -unsigned long long ulla, *ullap; +unsigned char uca; +const unsigned char *ucap; +const signed short *sap; +unsigned short usa; +const unsigned short *usap; +const signed long long *llap; +signed long long llb; +unsigned long long ulla; +const unsigned long long *ullap; vector signed long long test_vec_mul_sll(void) { // CHECK: mul <2 x i64> @@ -197,6 +201,36 @@ vector unsigned long long test_vcfuged(void) { return vec_cfuge(vulla, vullb); } +vector unsigned char test_vec_expandm_uc(void) { + // CHECK: @llvm.ppc.altivec.vexpandbm(<16 x i8> %{{.+}}) + // CHECK-NEXT: ret <16 x i8> + return vec_expandm(vuca); +} + +vector unsigned short test_vec_expandm_us(void) { + // CHECK: @llvm.ppc.altivec.vexpandhm(<8 x i16> %{{.+}}) + // CHECK-NEXT: ret <8 x i16> + return vec_expandm(vusa); +} + +vector unsigned int test_vec_expandm_ui(void) { + // CHECK: @llvm.ppc.altivec.vexpandwm(<4 x i32> %{{.+}}) + // CHECK-NEXT: ret <4 x i32> + return vec_expandm(vuia); +} + +vector unsigned long long test_vec_expandm_ull(void) { + // CHECK: @llvm.ppc.altivec.vexpanddm(<2 x i64> %{{.+}}) + // CHECK-NEXT: ret <2 x i64> + return vec_expandm(vulla); +} + +vector unsigned __int128 test_vec_expandm_u128(void) { + // CHECK: @llvm.ppc.altivec.vexpandqm(<1 x i128> %{{.+}}) + // CHECK-NEXT: ret <1 x i128> + return vec_expandm(vui128a); +} + unsigned long long test_vgnb_1(void) { // CHECK: @llvm.ppc.altivec.vgnb(<1 x i128> %{{.+}}, i32 2) // CHECK-NEXT: ret i64 @@ -928,6 +962,44 @@ int test_vec_test_lsbb_all_zeros(void) { return vec_test_lsbb_all_zeros(vuca); } +vector unsigned __int128 test_vec_mule_u128(void) { + // CHECK-BE: @llvm.ppc.altivec.vmuleud(<2 x i64> + // CHECK-BE-NEXT: ret <1 x i128> + // CHECK-LE: @llvm.ppc.altivec.vmuloud(<2 x i64> + // CHECK-LE-NEXT: ret <1 x i128> + return vec_mule(vulla, vullb); +} + +vector signed __int128 test_vec_mule_s128(void) { + // CHECK-BE: @llvm.ppc.altivec.vmulesd(<2 x i64> + // CHECK-BE-NEXT: ret <1 x i128> + // CHECK-LE: @llvm.ppc.altivec.vmulosd(<2 x i64> + // CHECK-LE-NEXT: ret <1 x i128> + return vec_mule(vslla, vsllb); +} + +vector unsigned __int128 test_vec_mulo_u128(void) { + // CHECK-BE: @llvm.ppc.altivec.vmuloud(<2 x i64> + // CHECK-BE-NEXT: ret <1 x i128> + // CHECK-LE: @llvm.ppc.altivec.vmuleud(<2 x i64> + // CHECK-LE-NEXT: ret <1 x i128> + return vec_mulo(vulla, vullb); +} + +vector signed __int128 test_vec_mulo_s128(void) { + // CHECK-BE: @llvm.ppc.altivec.vmulosd(<2 x i64> + // CHECK-BE-NEXT: ret <1 x i128> + // CHECK-LE: @llvm.ppc.altivec.vmulesd(<2 x i64> + // CHECK-LE-NEXT: ret <1 x i128> + return vec_mulo(vslla, vsllb); +} + +vector unsigned __int128 test_vec_msumc_u128(void) { + // CHECK: @llvm.ppc.altivec.vmsumcud(<2 x i64> + // CHECK-NEXT: ret <1 x i128> + return vec_msumc(vulla, vullb, vui128a); +} + vector signed __int128 test_vec_xl_sext_i8(void) { // CHECK: load i8 // CHECK: sext i8 diff --git a/clang/test/CodeGen/builtins-ppc-xl-xst.c b/clang/test/CodeGen/builtins-ppc-xl-xst.c index 8ad45376e9779..226e9d8aff4e6 100644 --- a/clang/test/CodeGen/builtins-ppc-xl-xst.c +++ b/clang/test/CodeGen/builtins-ppc-xl-xst.c @@ -17,10 +17,12 @@ // CHECK-NEXT: [[__PTR_ADDR_I:%.*]] = alloca i16*, align 8 // CHECK-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[C_ADDR:%.*]] = alloca <8 x i16>*, align 8 -// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca i16*, align 8 +// CHECK-NEXT: [[ST_ADDR:%.*]] = alloca i16*, align 8 +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca i16*, align 8 // CHECK-NEXT: store <8 x i16>* [[C:%.*]], <8 x i16>** [[C_ADDR]], align 8 -// CHECK-NEXT: store i16* [[PTR:%.*]], i16** [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load i16*, i16** [[PTR_ADDR]], align 8 +// CHECK-NEXT: store i16* [[ST:%.*]], i16** [[ST_ADDR]], align 8 +// CHECK-NEXT: store i16* [[LD:%.*]], i16** [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i16*, i16** [[LD_ADDR]], align 8 // CHECK-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-NEXT: store i16* [[TMP0]], i16** [[__PTR_ADDR_I]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load i16*, i16** [[__PTR_ADDR_I]], align 8 @@ -35,7 +37,7 @@ // CHECK-NEXT: store <8 x i16> [[TMP6]], <8 x i16>* [[TMP7]], align 16 // CHECK-NEXT: [[TMP8:%.*]] = load <8 x i16>*, <8 x i16>** [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, <8 x i16>* [[TMP8]], align 16 -// CHECK-NEXT: [[TMP10:%.*]] = load i16*, i16** [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load i16*, i16** [[ST_ADDR]], align 8 // CHECK-NEXT: store <8 x i16> [[TMP9]], <8 x i16>* [[__VEC_ADDR_I]], align 16 // CHECK-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-NEXT: store i16* [[TMP10]], i16** [[__PTR_ADDR_I2]], align 8 @@ -50,9 +52,9 @@ // CHECK-NEXT: store <8 x i16> [[TMP14]], <8 x i16>* [[TMP16]], align 1 // CHECK-NEXT: ret void // -void test1(vector signed short *c, signed short *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test1(vector signed short *c, signed short *st, const signed short *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } // CHECK-LABEL: @test2( @@ -65,10 +67,12 @@ void test1(vector signed short *c, signed short *ptr) { // CHECK-NEXT: [[__PTR_ADDR_I:%.*]] = alloca i16*, align 8 // CHECK-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[C_ADDR:%.*]] = alloca <8 x i16>*, align 8 -// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca i16*, align 8 +// CHECK-NEXT: [[ST_ADDR:%.*]] = alloca i16*, align 8 +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca i16*, align 8 // CHECK-NEXT: store <8 x i16>* [[C:%.*]], <8 x i16>** [[C_ADDR]], align 8 -// CHECK-NEXT: store i16* [[PTR:%.*]], i16** [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load i16*, i16** [[PTR_ADDR]], align 8 +// CHECK-NEXT: store i16* [[ST:%.*]], i16** [[ST_ADDR]], align 8 +// CHECK-NEXT: store i16* [[LD:%.*]], i16** [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i16*, i16** [[LD_ADDR]], align 8 // CHECK-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-NEXT: store i16* [[TMP0]], i16** [[__PTR_ADDR_I]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load i16*, i16** [[__PTR_ADDR_I]], align 8 @@ -83,7 +87,7 @@ void test1(vector signed short *c, signed short *ptr) { // CHECK-NEXT: store <8 x i16> [[TMP6]], <8 x i16>* [[TMP7]], align 16 // CHECK-NEXT: [[TMP8:%.*]] = load <8 x i16>*, <8 x i16>** [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, <8 x i16>* [[TMP8]], align 16 -// CHECK-NEXT: [[TMP10:%.*]] = load i16*, i16** [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load i16*, i16** [[ST_ADDR]], align 8 // CHECK-NEXT: store <8 x i16> [[TMP9]], <8 x i16>* [[__VEC_ADDR_I]], align 16 // CHECK-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-NEXT: store i16* [[TMP10]], i16** [[__PTR_ADDR_I2]], align 8 @@ -98,9 +102,10 @@ void test1(vector signed short *c, signed short *ptr) { // CHECK-NEXT: store <8 x i16> [[TMP14]], <8 x i16>* [[TMP16]], align 1 // CHECK-NEXT: ret void // -void test2(vector unsigned short *c, unsigned short *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test2(vector unsigned short *c, unsigned short *st, + const unsigned short *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } // CHECK-LABEL: @test3( @@ -113,10 +118,12 @@ void test2(vector unsigned short *c, unsigned short *ptr) { // CHECK-NEXT: [[__PTR_ADDR_I:%.*]] = alloca i32*, align 8 // CHECK-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[C_ADDR:%.*]] = alloca <4 x i32>*, align 8 -// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[ST_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca i32*, align 8 // CHECK-NEXT: store <4 x i32>* [[C:%.*]], <4 x i32>** [[C_ADDR]], align 8 -// CHECK-NEXT: store i32* [[PTR:%.*]], i32** [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[PTR_ADDR]], align 8 +// CHECK-NEXT: store i32* [[ST:%.*]], i32** [[ST_ADDR]], align 8 +// CHECK-NEXT: store i32* [[LD:%.*]], i32** [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[LD_ADDR]], align 8 // CHECK-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-NEXT: store i32* [[TMP0]], i32** [[__PTR_ADDR_I]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[__PTR_ADDR_I]], align 8 @@ -131,7 +138,7 @@ void test2(vector unsigned short *c, unsigned short *ptr) { // CHECK-NEXT: store <4 x i32> [[TMP6]], <4 x i32>* [[TMP7]], align 16 // CHECK-NEXT: [[TMP8:%.*]] = load <4 x i32>*, <4 x i32>** [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load <4 x i32>, <4 x i32>* [[TMP8]], align 16 -// CHECK-NEXT: [[TMP10:%.*]] = load i32*, i32** [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load i32*, i32** [[ST_ADDR]], align 8 // CHECK-NEXT: store <4 x i32> [[TMP9]], <4 x i32>* [[__VEC_ADDR_I]], align 16 // CHECK-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-NEXT: store i32* [[TMP10]], i32** [[__PTR_ADDR_I2]], align 8 @@ -146,9 +153,9 @@ void test2(vector unsigned short *c, unsigned short *ptr) { // CHECK-NEXT: store <4 x i32> [[TMP14]], <4 x i32>* [[TMP16]], align 1 // CHECK-NEXT: ret void // -void test3(vector signed int *c, signed int *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test3(vector signed int *c, signed int *st, const signed int *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } // CHECK-LABEL: @test4( @@ -161,10 +168,12 @@ void test3(vector signed int *c, signed int *ptr) { // CHECK-NEXT: [[__PTR_ADDR_I:%.*]] = alloca i32*, align 8 // CHECK-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[C_ADDR:%.*]] = alloca <4 x i32>*, align 8 -// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[ST_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca i32*, align 8 // CHECK-NEXT: store <4 x i32>* [[C:%.*]], <4 x i32>** [[C_ADDR]], align 8 -// CHECK-NEXT: store i32* [[PTR:%.*]], i32** [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[PTR_ADDR]], align 8 +// CHECK-NEXT: store i32* [[ST:%.*]], i32** [[ST_ADDR]], align 8 +// CHECK-NEXT: store i32* [[LD:%.*]], i32** [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[LD_ADDR]], align 8 // CHECK-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-NEXT: store i32* [[TMP0]], i32** [[__PTR_ADDR_I]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[__PTR_ADDR_I]], align 8 @@ -179,7 +188,7 @@ void test3(vector signed int *c, signed int *ptr) { // CHECK-NEXT: store <4 x i32> [[TMP6]], <4 x i32>* [[TMP7]], align 16 // CHECK-NEXT: [[TMP8:%.*]] = load <4 x i32>*, <4 x i32>** [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load <4 x i32>, <4 x i32>* [[TMP8]], align 16 -// CHECK-NEXT: [[TMP10:%.*]] = load i32*, i32** [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load i32*, i32** [[ST_ADDR]], align 8 // CHECK-NEXT: store <4 x i32> [[TMP9]], <4 x i32>* [[__VEC_ADDR_I]], align 16 // CHECK-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-NEXT: store i32* [[TMP10]], i32** [[__PTR_ADDR_I2]], align 8 @@ -194,9 +203,9 @@ void test3(vector signed int *c, signed int *ptr) { // CHECK-NEXT: store <4 x i32> [[TMP14]], <4 x i32>* [[TMP16]], align 1 // CHECK-NEXT: ret void // -void test4(vector unsigned int *c, unsigned int *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test4(vector unsigned int *c, unsigned int *st, const unsigned int *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } // CHECK-LABEL: @test5( @@ -209,10 +218,12 @@ void test4(vector unsigned int *c, unsigned int *ptr) { // CHECK-NEXT: [[__PTR_ADDR_I:%.*]] = alloca i64*, align 8 // CHECK-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[C_ADDR:%.*]] = alloca <2 x i64>*, align 8 -// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca i64*, align 8 +// CHECK-NEXT: [[ST_ADDR:%.*]] = alloca i64*, align 8 +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca i64*, align 8 // CHECK-NEXT: store <2 x i64>* [[C:%.*]], <2 x i64>** [[C_ADDR]], align 8 -// CHECK-NEXT: store i64* [[PTR:%.*]], i64** [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load i64*, i64** [[PTR_ADDR]], align 8 +// CHECK-NEXT: store i64* [[ST:%.*]], i64** [[ST_ADDR]], align 8 +// CHECK-NEXT: store i64* [[LD:%.*]], i64** [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64*, i64** [[LD_ADDR]], align 8 // CHECK-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-NEXT: store i64* [[TMP0]], i64** [[__PTR_ADDR_I]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load i64*, i64** [[__PTR_ADDR_I]], align 8 @@ -227,7 +238,7 @@ void test4(vector unsigned int *c, unsigned int *ptr) { // CHECK-NEXT: store <2 x i64> [[TMP6]], <2 x i64>* [[TMP7]], align 16 // CHECK-NEXT: [[TMP8:%.*]] = load <2 x i64>*, <2 x i64>** [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load <2 x i64>, <2 x i64>* [[TMP8]], align 16 -// CHECK-NEXT: [[TMP10:%.*]] = load i64*, i64** [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load i64*, i64** [[ST_ADDR]], align 8 // CHECK-NEXT: store <2 x i64> [[TMP9]], <2 x i64>* [[__VEC_ADDR_I]], align 16 // CHECK-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-NEXT: store i64* [[TMP10]], i64** [[__PTR_ADDR_I2]], align 8 @@ -242,9 +253,10 @@ void test4(vector unsigned int *c, unsigned int *ptr) { // CHECK-NEXT: store <2 x i64> [[TMP14]], <2 x i64>* [[TMP16]], align 1 // CHECK-NEXT: ret void // -void test5(vector signed long long *c, signed long long *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test5(vector signed long long *c, signed long long *st, + const signed long long *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } // CHECK-LABEL: @test6( @@ -257,10 +269,12 @@ void test5(vector signed long long *c, signed long long *ptr) { // CHECK-NEXT: [[__PTR_ADDR_I:%.*]] = alloca i64*, align 8 // CHECK-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[C_ADDR:%.*]] = alloca <2 x i64>*, align 8 -// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca i64*, align 8 +// CHECK-NEXT: [[ST_ADDR:%.*]] = alloca i64*, align 8 +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca i64*, align 8 // CHECK-NEXT: store <2 x i64>* [[C:%.*]], <2 x i64>** [[C_ADDR]], align 8 -// CHECK-NEXT: store i64* [[PTR:%.*]], i64** [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load i64*, i64** [[PTR_ADDR]], align 8 +// CHECK-NEXT: store i64* [[ST:%.*]], i64** [[ST_ADDR]], align 8 +// CHECK-NEXT: store i64* [[LD:%.*]], i64** [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64*, i64** [[LD_ADDR]], align 8 // CHECK-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-NEXT: store i64* [[TMP0]], i64** [[__PTR_ADDR_I]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load i64*, i64** [[__PTR_ADDR_I]], align 8 @@ -275,7 +289,7 @@ void test5(vector signed long long *c, signed long long *ptr) { // CHECK-NEXT: store <2 x i64> [[TMP6]], <2 x i64>* [[TMP7]], align 16 // CHECK-NEXT: [[TMP8:%.*]] = load <2 x i64>*, <2 x i64>** [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load <2 x i64>, <2 x i64>* [[TMP8]], align 16 -// CHECK-NEXT: [[TMP10:%.*]] = load i64*, i64** [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load i64*, i64** [[ST_ADDR]], align 8 // CHECK-NEXT: store <2 x i64> [[TMP9]], <2 x i64>* [[__VEC_ADDR_I]], align 16 // CHECK-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-NEXT: store i64* [[TMP10]], i64** [[__PTR_ADDR_I2]], align 8 @@ -290,9 +304,10 @@ void test5(vector signed long long *c, signed long long *ptr) { // CHECK-NEXT: store <2 x i64> [[TMP14]], <2 x i64>* [[TMP16]], align 1 // CHECK-NEXT: ret void // -void test6(vector unsigned long long *c, unsigned long long *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test6(vector unsigned long long *c, unsigned long long *st, + const unsigned long long *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } // CHECK-LABEL: @test7( @@ -305,10 +320,12 @@ void test6(vector unsigned long long *c, unsigned long long *ptr) { // CHECK-NEXT: [[__PTR_ADDR_I:%.*]] = alloca float*, align 8 // CHECK-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[C_ADDR:%.*]] = alloca <4 x float>*, align 8 -// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca float*, align 8 +// CHECK-NEXT: [[ST_ADDR:%.*]] = alloca float*, align 8 +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca float*, align 8 // CHECK-NEXT: store <4 x float>* [[C:%.*]], <4 x float>** [[C_ADDR]], align 8 -// CHECK-NEXT: store float* [[PTR:%.*]], float** [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load float*, float** [[PTR_ADDR]], align 8 +// CHECK-NEXT: store float* [[ST:%.*]], float** [[ST_ADDR]], align 8 +// CHECK-NEXT: store float* [[LD:%.*]], float** [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load float*, float** [[LD_ADDR]], align 8 // CHECK-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-NEXT: store float* [[TMP0]], float** [[__PTR_ADDR_I]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load float*, float** [[__PTR_ADDR_I]], align 8 @@ -323,7 +340,7 @@ void test6(vector unsigned long long *c, unsigned long long *ptr) { // CHECK-NEXT: store <4 x float> [[TMP6]], <4 x float>* [[TMP7]], align 16 // CHECK-NEXT: [[TMP8:%.*]] = load <4 x float>*, <4 x float>** [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load <4 x float>, <4 x float>* [[TMP8]], align 16 -// CHECK-NEXT: [[TMP10:%.*]] = load float*, float** [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load float*, float** [[ST_ADDR]], align 8 // CHECK-NEXT: store <4 x float> [[TMP9]], <4 x float>* [[__VEC_ADDR_I]], align 16 // CHECK-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-NEXT: store float* [[TMP10]], float** [[__PTR_ADDR_I2]], align 8 @@ -338,9 +355,9 @@ void test6(vector unsigned long long *c, unsigned long long *ptr) { // CHECK-NEXT: store <4 x float> [[TMP14]], <4 x float>* [[TMP16]], align 1 // CHECK-NEXT: ret void // -void test7(vector float *c, float *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test7(vector float *c, float *st, const float *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } // CHECK-LABEL: @test8( @@ -353,10 +370,12 @@ void test7(vector float *c, float *ptr) { // CHECK-NEXT: [[__PTR_ADDR_I:%.*]] = alloca double*, align 8 // CHECK-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[C_ADDR:%.*]] = alloca <2 x double>*, align 8 -// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca double*, align 8 +// CHECK-NEXT: [[ST_ADDR:%.*]] = alloca double*, align 8 +// CHECK-NEXT: [[LD_ADDR:%.*]] = alloca double*, align 8 // CHECK-NEXT: store <2 x double>* [[C:%.*]], <2 x double>** [[C_ADDR]], align 8 -// CHECK-NEXT: store double* [[PTR:%.*]], double** [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[TMP0:%.*]] = load double*, double** [[PTR_ADDR]], align 8 +// CHECK-NEXT: store double* [[ST:%.*]], double** [[ST_ADDR]], align 8 +// CHECK-NEXT: store double* [[LD:%.*]], double** [[LD_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double*, double** [[LD_ADDR]], align 8 // CHECK-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-NEXT: store double* [[TMP0]], double** [[__PTR_ADDR_I]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[__PTR_ADDR_I]], align 8 @@ -371,7 +390,7 @@ void test7(vector float *c, float *ptr) { // CHECK-NEXT: store <2 x double> [[TMP6]], <2 x double>* [[TMP7]], align 16 // CHECK-NEXT: [[TMP8:%.*]] = load <2 x double>*, <2 x double>** [[C_ADDR]], align 8 // CHECK-NEXT: [[TMP9:%.*]] = load <2 x double>, <2 x double>* [[TMP8]], align 16 -// CHECK-NEXT: [[TMP10:%.*]] = load double*, double** [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load double*, double** [[ST_ADDR]], align 8 // CHECK-NEXT: store <2 x double> [[TMP9]], <2 x double>* [[__VEC_ADDR_I]], align 16 // CHECK-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-NEXT: store double* [[TMP10]], double** [[__PTR_ADDR_I2]], align 8 @@ -386,9 +405,9 @@ void test7(vector float *c, float *ptr) { // CHECK-NEXT: store <2 x double> [[TMP14]], <2 x double>* [[TMP16]], align 1 // CHECK-NEXT: ret void // -void test8(vector double *c, double *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test8(vector double *c, double *st, const double *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } #ifdef __POWER8_VECTOR__ @@ -402,10 +421,12 @@ void test8(vector double *c, double *ptr) { // CHECK-P8-NEXT: [[__PTR_ADDR_I:%.*]] = alloca i128*, align 8 // CHECK-P8-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-P8-NEXT: [[C_ADDR:%.*]] = alloca <1 x i128>*, align 8 -// CHECK-P8-NEXT: [[PTR_ADDR:%.*]] = alloca i128*, align 8 +// CHECK-P8-NEXT: [[ST_ADDR:%.*]] = alloca i128*, align 8 +// CHECK-P8-NEXT: [[LD_ADDR:%.*]] = alloca i128*, align 8 // CHECK-P8-NEXT: store <1 x i128>* [[C:%.*]], <1 x i128>** [[C_ADDR]], align 8 -// CHECK-P8-NEXT: store i128* [[PTR:%.*]], i128** [[PTR_ADDR]], align 8 -// CHECK-P8-NEXT: [[TMP0:%.*]] = load i128*, i128** [[PTR_ADDR]], align 8 +// CHECK-P8-NEXT: store i128* [[ST:%.*]], i128** [[ST_ADDR]], align 8 +// CHECK-P8-NEXT: store i128* [[LD:%.*]], i128** [[LD_ADDR]], align 8 +// CHECK-P8-NEXT: [[TMP0:%.*]] = load i128*, i128** [[LD_ADDR]], align 8 // CHECK-P8-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-P8-NEXT: store i128* [[TMP0]], i128** [[__PTR_ADDR_I]], align 8 // CHECK-P8-NEXT: [[TMP1:%.*]] = load i128*, i128** [[__PTR_ADDR_I]], align 8 @@ -420,7 +441,7 @@ void test8(vector double *c, double *ptr) { // CHECK-P8-NEXT: store <1 x i128> [[TMP6]], <1 x i128>* [[TMP7]], align 16 // CHECK-P8-NEXT: [[TMP8:%.*]] = load <1 x i128>*, <1 x i128>** [[C_ADDR]], align 8 // CHECK-P8-NEXT: [[TMP9:%.*]] = load <1 x i128>, <1 x i128>* [[TMP8]], align 16 -// CHECK-P8-NEXT: [[TMP10:%.*]] = load i128*, i128** [[PTR_ADDR]], align 8 +// CHECK-P8-NEXT: [[TMP10:%.*]] = load i128*, i128** [[ST_ADDR]], align 8 // CHECK-P8-NEXT: store <1 x i128> [[TMP9]], <1 x i128>* [[__VEC_ADDR_I]], align 16 // CHECK-P8-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-P8-NEXT: store i128* [[TMP10]], i128** [[__PTR_ADDR_I2]], align 8 @@ -435,9 +456,10 @@ void test8(vector double *c, double *ptr) { // CHECK-P8-NEXT: store <1 x i128> [[TMP14]], <1 x i128>* [[TMP16]], align 1 // CHECK-P8-NEXT: ret void // -void test9(vector signed __int128 *c, signed __int128 *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test9(vector signed __int128 *c, signed __int128 *st, + const signed __int128 *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } // CHECK-P8-LABEL: @test10( @@ -450,10 +472,12 @@ void test9(vector signed __int128 *c, signed __int128 *ptr) { // CHECK-P8-NEXT: [[__PTR_ADDR_I:%.*]] = alloca i128*, align 8 // CHECK-P8-NEXT: [[__ADDR_I:%.*]] = alloca i8*, align 8 // CHECK-P8-NEXT: [[C_ADDR:%.*]] = alloca <1 x i128>*, align 8 -// CHECK-P8-NEXT: [[PTR_ADDR:%.*]] = alloca i128*, align 8 +// CHECK-P8-NEXT: [[ST_ADDR:%.*]] = alloca i128*, align 8 +// CHECK-P8-NEXT: [[LD_ADDR:%.*]] = alloca i128*, align 8 // CHECK-P8-NEXT: store <1 x i128>* [[C:%.*]], <1 x i128>** [[C_ADDR]], align 8 -// CHECK-P8-NEXT: store i128* [[PTR:%.*]], i128** [[PTR_ADDR]], align 8 -// CHECK-P8-NEXT: [[TMP0:%.*]] = load i128*, i128** [[PTR_ADDR]], align 8 +// CHECK-P8-NEXT: store i128* [[ST:%.*]], i128** [[ST_ADDR]], align 8 +// CHECK-P8-NEXT: store i128* [[LD:%.*]], i128** [[LD_ADDR]], align 8 +// CHECK-P8-NEXT: [[TMP0:%.*]] = load i128*, i128** [[LD_ADDR]], align 8 // CHECK-P8-NEXT: store i64 3, i64* [[__OFFSET_ADDR_I]], align 8 // CHECK-P8-NEXT: store i128* [[TMP0]], i128** [[__PTR_ADDR_I]], align 8 // CHECK-P8-NEXT: [[TMP1:%.*]] = load i128*, i128** [[__PTR_ADDR_I]], align 8 @@ -468,7 +492,7 @@ void test9(vector signed __int128 *c, signed __int128 *ptr) { // CHECK-P8-NEXT: store <1 x i128> [[TMP6]], <1 x i128>* [[TMP7]], align 16 // CHECK-P8-NEXT: [[TMP8:%.*]] = load <1 x i128>*, <1 x i128>** [[C_ADDR]], align 8 // CHECK-P8-NEXT: [[TMP9:%.*]] = load <1 x i128>, <1 x i128>* [[TMP8]], align 16 -// CHECK-P8-NEXT: [[TMP10:%.*]] = load i128*, i128** [[PTR_ADDR]], align 8 +// CHECK-P8-NEXT: [[TMP10:%.*]] = load i128*, i128** [[ST_ADDR]], align 8 // CHECK-P8-NEXT: store <1 x i128> [[TMP9]], <1 x i128>* [[__VEC_ADDR_I]], align 16 // CHECK-P8-NEXT: store i64 7, i64* [[__OFFSET_ADDR_I1]], align 8 // CHECK-P8-NEXT: store i128* [[TMP10]], i128** [[__PTR_ADDR_I2]], align 8 @@ -483,8 +507,9 @@ void test9(vector signed __int128 *c, signed __int128 *ptr) { // CHECK-P8-NEXT: store <1 x i128> [[TMP14]], <1 x i128>* [[TMP16]], align 1 // CHECK-P8-NEXT: ret void // -void test10(vector unsigned __int128 *c, unsigned __int128 *ptr) { - *c = vec_xl(3ll, ptr); - vec_xst(*c, 7ll, ptr); +void test10(vector unsigned __int128 *c, unsigned __int128 *st, + const unsigned __int128 *ld) { + *c = vec_xl(3ll, ld); + vec_xst(*c, 7ll, st); } #endif diff --git a/clang/test/CodeGen/ssse3-builtins.c b/clang/test/CodeGen/ssse3-builtins.c index b89955fdc0880..d72ca9dd5b41c 100644 --- a/clang/test/CodeGen/ssse3-builtins.c +++ b/clang/test/CodeGen/ssse3-builtins.c @@ -7,25 +7,19 @@ __m128i test_mm_abs_epi8(__m128i a) { // CHECK-LABEL: test_mm_abs_epi8 - // CHECK: [[SUB:%.+]] = sub <16 x i8> zeroinitializer, [[A:%.+]] - // CHECK: [[CMP:%.+]] = icmp sgt <16 x i8> [[A]], zeroinitializer - // CHECK: %{{.*}} = select <16 x i1> [[CMP]], <16 x i8> [[A]], <16 x i8> [[SUB]] + // CHECK: [[ABS:%.*]] = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %{{.*}}, i1 false) return _mm_abs_epi8(a); } __m128i test_mm_abs_epi16(__m128i a) { // CHECK-LABEL: test_mm_abs_epi16 - // CHECK: [[SUB:%.+]] = sub <8 x i16> zeroinitializer, [[A:%.+]] - // CHECK: [[CMP:%.+]] = icmp sgt <8 x i16> [[A]], zeroinitializer - // CHECK: %{{.*}} = select <8 x i1> [[CMP]], <8 x i16> [[A]], <8 x i16> [[SUB]] + // CHECK: [[ABS:%.*]] = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %{{.*}}, i1 false) return _mm_abs_epi16(a); } __m128i test_mm_abs_epi32(__m128i a) { // CHECK-LABEL: test_mm_abs_epi32 - // CHECK: [[SUB:%.+]] = sub <4 x i32> zeroinitializer, [[A:%.+]] - // CHECK: [[CMP:%.+]] = icmp sgt <4 x i32> [[A]], zeroinitializer - // CHECK: %{{.*}} = select <4 x i1> [[CMP]], <4 x i32> [[A]], <4 x i32> [[SUB]] + // CHECK: [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %{{.*}}, i1 false) return _mm_abs_epi32(a); } diff --git a/clang/test/CodeGenCUDA/amdgpu-kernel-attrs.cu b/clang/test/CodeGenCUDA/amdgpu-kernel-attrs.cu index 7a9fd2527272a..5415bddffc899 100644 --- a/clang/test/CodeGenCUDA/amdgpu-kernel-attrs.cu +++ b/clang/test/CodeGenCUDA/amdgpu-kernel-attrs.cu @@ -39,7 +39,7 @@ __global__ void num_vgpr_64() { // NAMD-NOT: "amdgpu-num-vgpr" // NAMD-NOT: "amdgpu-num-sgpr" -// DEFAULT-DAG: attributes [[FLAT_WORK_GROUP_SIZE_DEFAULT]] = {{.*}}"amdgpu-flat-work-group-size"="1,1024"{{.*}}"uniform-work-group-size"="true" +// DEFAULT-DAG: attributes [[FLAT_WORK_GROUP_SIZE_DEFAULT]] = {{.*}}"amdgpu-flat-work-group-size"="1,256"{{.*}}"uniform-work-group-size"="true" // MAX1024-DAG: attributes [[FLAT_WORK_GROUP_SIZE_DEFAULT]] = {{.*}}"amdgpu-flat-work-group-size"="1,1024" // CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64]] = {{.*}}"amdgpu-flat-work-group-size"="32,64" // CHECK-DAG: attributes [[WAVES_PER_EU_2]] = {{.*}}"amdgpu-waves-per-eu"="2" diff --git a/clang/test/CodeGenCUDA/kernel-amdgcn.cu b/clang/test/CodeGenCUDA/kernel-amdgcn.cu index 6066469f76470..135d3030480c6 100644 --- a/clang/test/CodeGenCUDA/kernel-amdgcn.cu +++ b/clang/test/CodeGenCUDA/kernel-amdgcn.cu @@ -39,4 +39,4 @@ int main() { launch((void*)D.Empty()); return 0; } -// CHECK: attributes #[[ATTR]] = {{.*}}"amdgpu-flat-work-group-size"="1,1024" +// CHECK: attributes #[[ATTR]] = {{.*}}"amdgpu-flat-work-group-size"="1,256" diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sve-fixed-vectors.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sve-fixed-vectors.cpp index cb001cd06e02e..12550396d0fe7 100644 --- a/clang/test/CodeGenCXX/aarch64-mangle-sve-fixed-vectors.cpp +++ b/clang/test/CodeGenCXX/aarch64-mangle-sve-fixed-vectors.cpp @@ -14,7 +14,7 @@ // RUN: -target-feature +sve -target-feature +bf16 -msve-vector-bits=2048 \ // RUN: | FileCheck %s --check-prefix=CHECK-2048 -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef __SVInt8_t fixed_int8_t __attribute__((arm_sve_vector_bits(N))); typedef __SVInt16_t fixed_int16_t __attribute__((arm_sve_vector_bits(N))); diff --git a/clang/test/CodeGenCXX/aarch64-sve-fixedtypeinfo.cpp b/clang/test/CodeGenCXX/aarch64-sve-fixedtypeinfo.cpp index 7308aa6ae7a45..e9e15d6e0c4e5 100644 --- a/clang/test/CodeGenCXX/aarch64-sve-fixedtypeinfo.cpp +++ b/clang/test/CodeGenCXX/aarch64-sve-fixedtypeinfo.cpp @@ -14,7 +14,7 @@ // RUN: -target-feature +sve -target-feature +bf16 -msve-vector-bits=2048 \ // RUN: | FileCheck %s --check-prefix=CHECK-2048 -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS namespace std { class type_info; diff --git a/clang/test/CodeGenCXX/debug-info-class.cpp b/clang/test/CodeGenCXX/debug-info-class.cpp index 94d5a0f1f0820..e000532b8c3b1 100644 --- a/clang/test/CodeGenCXX/debug-info-class.cpp +++ b/clang/test/CodeGenCXX/debug-info-class.cpp @@ -136,7 +136,7 @@ int main(int argc, char **argv) { // CHECK: [[C_DTOR]] = !DISubprogram(name: "~C" // CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D" -// CHECK-NOT: size: +// CHECK-SAME: size: // CHECK-SAME: DIFlagFwdDecl // CHECK-NOT: identifier: // CHECK-SAME: ){{$}} diff --git a/clang/test/CodeGenCXX/visibility-inlines-hidden-static-local-var.cpp b/clang/test/CodeGenCXX/visibility-inlines-hidden-static-local-var.cpp new file mode 100644 index 0000000000000..57e6dea72e21f --- /dev/null +++ b/clang/test/CodeGenCXX/visibility-inlines-hidden-static-local-var.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fvisibility-inlines-hidden -fvisibility-inlines-hidden-static-local-var %s -emit-llvm -o - | FileCheck %s + +#define used __attribute__((used)) + +used inline void f1() { + // CHECK: @_ZZ2f1vE6f1_var = linkonce_odr hidden global i32 0 + static int f1_var = 0; +} + +__attribute__((visibility("default"))) +used inline void f2() { + // CHECK: @_ZZ2f2vE6f2_var = linkonce_odr global i32 0 + static int f2_var = 0; +} + +struct S { + used void f3() { + // CHECK: @_ZZN1S2f3EvE6f3_var = linkonce_odr hidden global i32 0 + static int f3_var = 0; + } + + void f6(); + void f7(); +}; + +used void f4() { + // CHECK: @_ZZ2f4vE6f4_var = internal global i32 0 + static int f4_var = 0; +} + +__attribute__((visibility("default"))) +used void f5() { + // CHECK: @_ZZ2f5vE6f5_var = internal global i32 0 + static int f5_var = 0; +} + +used void S::f6() { + // CHECK: @_ZZN1S2f6EvE6f6_var = internal global i32 0 + static int f6_var = 0; +} + +used inline void S::f7() { + // CHECK: @_ZZN1S2f7EvE6f7_var = linkonce_odr hidden global i32 0 + static int f7_var = 0; +} + + +struct __attribute__((visibility("default"))) S2 { + used void f8() { + // CHECK: @_ZZN2S22f8EvE6f8_var = linkonce_odr hidden global i32 0 + static int f8_var = 0; + } +}; diff --git a/clang/test/CodeGenObjC/attr-used-on-method.m b/clang/test/CodeGenObjC/attr-used-on-method.m new file mode 100644 index 0000000000000..d8b2a5d291841 --- /dev/null +++ b/clang/test/CodeGenObjC/attr-used-on-method.m @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 %s -S -emit-llvm -o - | FileCheck %s + +// CHECK: @llvm.used = +// CHECK-SAME: @"\01-[X m]" + +// CHECK: define internal void @"\01-[X m]"( + +@interface X @end +@implementation X +-(void) m __attribute__((used)) {} +@end diff --git a/clang/test/CodeGenSYCL/Inputs/sycl.hpp b/clang/test/CodeGenSYCL/Inputs/sycl.hpp index 0d77fd81dc7da..e266ae3d3bea5 100644 --- a/clang/test/CodeGenSYCL/Inputs/sycl.hpp +++ b/clang/test/CodeGenSYCL/Inputs/sycl.hpp @@ -71,19 +71,11 @@ enum prop_type { base_prop }; -// Compile time known accessor property -// TODO: this doesn't belong to property namespace, instead it shall be in its -// own namespace. Change it, when the actual implementation in SYCL headers is -// ready -template -class buffer_location {}; - struct property_base { virtual prop_type type() const = 0; }; } // namespace property -template class property_list { public: template @@ -102,6 +94,20 @@ class property_list { bool operator!=(const property_list &rhs) const { return false; } }; +namespace INTEL { +namespace property { +// Compile time known accessor property +struct buffer_location { + template class instance {}; +}; +} // namespace property +} // namespace INTEL + +namespace ONEAPI { +template +class accessor_property_list {}; +} // namespace ONEAPI + template struct id { template @@ -136,7 +142,7 @@ struct _ImplT { template > + typename propertyListT = ONEAPI::accessor_property_list<>> class accessor { public: @@ -150,8 +156,6 @@ class accessor { private: void __init(__attribute__((opencl_global)) dataT *Ptr, range AccessRange, range MemRange, id Offset) {} - - propertyListT prop_list; }; template @@ -339,8 +343,7 @@ const stream& operator<<(const stream &S, T&&) { } template + typename AllocatorT = int /*fake type as AllocatorT is not used*/> class buffer { public: using value_type = T; @@ -352,13 +355,13 @@ class buffer { buffer(ParamTypes... args) {} // fake constructor buffer(const range &bufferRange, - const property_list &propList = {}) {} + const property_list &propList = {}) {} buffer(T *hostData, const range &bufferRange, - const property_list &propList = {}) {} + const property_list &propList = {}) {} buffer(const T *hostData, const range &bufferRange, - const property_list &propList = {}) {} + const property_list &propList = {}) {} buffer(const buffer &rhs) = default; @@ -426,12 +429,12 @@ enum class image_channel_type : unsigned int { fp32 }; -template +template class image { public: image(image_channel_order Order, image_channel_type Type, const range &Range, - const property_list &PropList = {}) {} + const property_list &PropList = {}) {} /* -- common interface members -- */ diff --git a/clang/test/CodeGenSYCL/accessor_inheritance.cpp b/clang/test/CodeGenSYCL/accessor_inheritance.cpp index 47705df10dfbf..f6d93002e9407 100644 --- a/clang/test/CodeGenSYCL/accessor_inheritance.cpp +++ b/clang/test/CodeGenSYCL/accessor_inheritance.cpp @@ -67,13 +67,13 @@ int main() { // CHECK: [[ACC_FIELD:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct{{.*}}Base, %struct{{.*}}Base* [[BITCAST]], i32 0, i32 2 // CHECK: [[ACC1_AS_CAST:%[a-zA-Z0-9_]+]] = addrspacecast %"class{{.*}}cl::sycl::accessor"* [[ACC_FIELD]] to %"class{{.*}}cl::sycl::accessor" addrspace(4)* // Default constructor call -// CHECK: call spir_func void @_ZN2cl4sycl8accessorIcLi1ELNS0_6access4modeE1024ELNS2_6targetE2014ELNS2_11placeholderE0ENS0_13property_listIJEEEEC1Ev(%"class{{.*}}cl::sycl::accessor" addrspace(4)* [[ACC1_AS_CAST]]) +// CHECK: call spir_func void @_ZN2cl4sycl8accessorIcLi1ELNS0_6access4modeE1024ELNS2_6targetE2014ELNS2_11placeholderE0ENS0_6ONEAPI22accessor_property_listIJEEEEC1Ev(%"class{{.*}}cl::sycl::accessor" addrspace(4)* [[ACC1_AS_CAST]]) // CHECK: [[BITCAST1:%[a-zA-Z0-9_]+]] = bitcast %struct{{.*}}Captured* [[GEP]] to i8* -// CHECK: [[GEP1:%[a-zA-Z0-9_]+]] = getelementptr inbounds i8, i8* [[BITCAST1]], i64 24 +// CHECK: [[GEP1:%[a-zA-Z0-9_]+]] = getelementptr inbounds i8, i8* [[BITCAST1]], i64 20 // CHECK: [[BITCAST2:%[a-zA-Z0-9_]+]] = bitcast i8* [[GEP1]] to %"class{{.*}}cl::sycl::accessor"* // CHECK: [[ACC2_AS_CAST:%[a-zA-Z0-9_]+]] = addrspacecast %"class{{.*}}cl::sycl::accessor"* [[BITCAST2]] to %"class{{.*}}cl::sycl::accessor" addrspace(4)* // Default constructor call -// CHECK: call spir_func void @_ZN2cl4sycl8accessorIcLi1ELNS0_6access4modeE1024ELNS2_6targetE2014ELNS2_11placeholderE0ENS0_13property_listIJEEEEC2Ev(%"class{{.*}}cl::sycl::accessor" addrspace(4)* [[ACC2_AS_CAST]]) +// CHECK: call spir_func void @_ZN2cl4sycl8accessorIcLi1ELNS0_6access4modeE1024ELNS2_6targetE2014ELNS2_11placeholderE0ENS0_6ONEAPI22accessor_property_listIJEEEEC2Ev(%"class{{.*}}cl::sycl::accessor" addrspace(4)* [[ACC2_AS_CAST]]) // CHECK C field initialization // CHECK: [[FIELD_C:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct{{.*}}Captured, %struct{{.*}}Captured* [[GEP]], i32 0, i32 2 diff --git a/clang/test/CodeGenSYCL/buffer_location.cpp b/clang/test/CodeGenSYCL/buffer_location.cpp index 0cf04c824d1a1..35448a9ff589b 100644 --- a/clang/test/CodeGenSYCL/buffer_location.cpp +++ b/clang/test/CodeGenSYCL/buffer_location.cpp @@ -10,8 +10,8 @@ struct Base { cl::sycl::accessor>> + cl::sycl::ONEAPI::accessor_property_list< + cl::sycl::INTEL::property::buffer_location::instance<2>>> AccField; }; @@ -19,8 +19,8 @@ struct Captured : Base, cl::sycl::accessor>> { + cl::sycl::ONEAPI::accessor_property_list< + cl::sycl::INTEL::property::buffer_location::instance<2>>> { int C; }; @@ -29,8 +29,8 @@ int main() { cl::sycl::accessor>> + cl::sycl::ONEAPI::accessor_property_list< + cl::sycl::INTEL::property::buffer_location::instance<3>>> accessorA; cl::sycl::kernel_single_task( [=]() { diff --git a/clang/test/CodeGenSYCL/debug-info-srcpos-kernel.cpp b/clang/test/CodeGenSYCL/debug-info-srcpos-kernel.cpp index 9aa1f4e3da80e..9c2300075f152 100644 --- a/clang/test/CodeGenSYCL/debug-info-srcpos-kernel.cpp +++ b/clang/test/CodeGenSYCL/debug-info-srcpos-kernel.cpp @@ -1,7 +1,7 @@ // RUN: %clang -fsycl-device-only %s -S -emit-llvm -O0 -g -o - | FileCheck %s // -// Verify the SYCL kernel routine is marked artificial and has no source -// correlation. +// Verify the SYCL kernel routine is marked artificial and has the +// expected source correlation. // // In order to placate the profiling tools, which can't cope with instructions // mapped to line 0, we've made the change so that the artificial code in a @@ -28,17 +28,13 @@ int main() { // CHECK: getelementptr inbounds %"class.{{.*}}.anon"{{.*}} !dbg [[LINE_A0:![0-9]+]] // CHECK: call spir_func void {{.*}}6__init{{.*}} !dbg [[LINE_A0]] // CHECK: call spir_func void @"_ZZ4mainENK3$_0clEv"{{.*}} !dbg [[LINE_B0:![0-9]+]] -// CHECK: ret void +// CHECK: ret void, !dbg [[LINE_C0:![0-9]+]] // CHECK: [[FILE:![0-9]+]] = !DIFile(filename: "{{.*}}debug-info-srcpos-kernel.cpp"{{.*}}) // CHECK: [[KERNEL]] = {{.*}}!DISubprogram(name: "{{.*}}19use_kernel_for_test" // CHECK-SAME: scope: [[FILE]] // CHECK-SAME: file: [[FILE]] // CHECK-SAME: flags: DIFlagArtificial | DIFlagPrototyped // CHECK: [[LINE_A0]] = !DILocation(line: 15,{{.*}}scope: [[KERNEL]] -// CHECK: [[LINE_B0]] = !DILocation(line: 0 - -// TODO: [[LINE_B0]] should be mapped to line 15 as well. That said, -// this 'line 0' assignment is less problematic as the lambda function -// call would be inlined in most cases. -// TODO: SYCL specific fail - analyze and enable -// XFAIL: windows-msvc +// CHECK: [[LINE_B0]] = !DILocation(line: 16,{{.*}}scope: [[BLOCK:![0-9]+]] +// CHECK: [[BLOCK]] = distinct !DILexicalBlock(scope: [[KERNEL]] +// CHECK: [[LINE_C0]] = !DILocation(line: 17,{{.*}}scope: [[KERNEL]] diff --git a/clang/test/CodeGenSYCL/inheritance.cpp b/clang/test/CodeGenSYCL/inheritance.cpp index 9cbea0ca8de48..b5007d1885447 100644 --- a/clang/test/CodeGenSYCL/inheritance.cpp +++ b/clang/test/CodeGenSYCL/inheritance.cpp @@ -4,7 +4,7 @@ class second_base { public: - int e; + int *e; }; class InnerFieldBase { @@ -40,45 +40,33 @@ int main() { } // Check kernel paramters -// CHECK: define spir_kernel void @{{.*}}derived(i32 %_arg_b, i32 %_arg_d, i32 %_arg_c, i32 %_arg_e, i32 %_arg_a) +// CHECK: define spir_kernel void @{{.*}}derived(%struct.{{.*}}.base* byval(%struct.{{.*}}.base) align 4 %_arg__base, %struct.{{.*}}.__wrapper_class* byval(%struct.{{.*}}.__wrapper_class) align 8 %_arg_e, i32 %_arg_a) // Check alloca for kernel paramters -// CHECK: %[[ARG_B:[a-zA-Z0-9_.]+]] = alloca i32, align 4 -// CHECK: %[[ARG_D:[a-zA-Z0-9_.]+]] = alloca i32, align 4 -// CHECK: %[[ARG_C:[a-zA-Z0-9_.]+]] = alloca i32, align 4 -// CHECK: %[[ARG_E:[a-zA-Z0-9_.]+]] = alloca i32, align 4 // CHECK: %[[ARG_A:[a-zA-Z0-9_.]+]] = alloca i32, align 4 - // Check alloca for local functor object -// CHECK: %[[LOCAL_OBJECT:[a-zA-Z0-9_.]+]] = alloca %struct.{{.*}}.derived, align 4 - -// Initialize field 'b' -// CHECK: %[[BITCAST1:[0-9]+]] = bitcast %struct.{{.*}}.derived* %[[LOCAL_OBJECT]] to %struct.{{.*}}.base* -// CHECK: %[[GEP_B:[a-zA-Z0-9]+]] = getelementptr inbounds %struct.{{.*}}.base, %struct.{{.*}}.base* %[[BITCAST1]], i32 0, i32 0 -// CHECK: %[[LOAD_B:[0-9]+]] = load i32, i32* %[[ARG_B]], align 4 -// CHECK: store i32 %[[LOAD_B]], i32* %[[GEP_B]], align 4 - -// Initialize field 'd' -// CHECK: %[[GEP_OBJ:[a-zA-Z0-9]+]] = getelementptr inbounds %struct.{{.*}}.base, %struct.{{.*}}.base* %[[BITCAST1]], i32 0, i32 1 -// CHECK: %[[BITCAST2:[0-9]+]] = bitcast %class.{{.*}}.InnerField* %[[GEP_OBJ]] to %class.{{.*}}.InnerFieldBase* -// CHECK: %[[GEP_D:[a-zA-Z0-9]+]] = getelementptr inbounds %class.{{.*}}.InnerFieldBase, %class.{{.*}}.InnerFieldBase* %[[BITCAST2]], i32 0, i32 0 -// CHECK: %[[LOAD_D:[0-9]+]] = load i32, i32* %[[ARG_D]], align 4 -// CHECK: store i32 %[[LOAD_D]], i32* %[[GEP_D]], align 4 - -// Initialize field 'c' -// CHECK: %[[GEP_C:[a-zA-Z0-9]+]] = getelementptr inbounds %class.{{.*}}.InnerField, %class.{{.*}}.InnerField* %[[GEP_OBJ]], i32 0, i32 1 -// CHECK: %[[LOAD_C:[0-9]+]] = load i32, i32* %[[ARG_C]], align 4 -// CHECK: store i32 %[[LOAD_C]], i32* %[[GEP_C]], align 4 - -// Initialize field 'e' -// CHECK: %[[BITCAST3:[0-9]+]] = bitcast %struct.{{.*}}.derived* %[[LOCAL_OBJECT]] to i8* -// CHECK: %[[GEP_DERIVED:[a-zA-Z0-9]+]] = getelementptr inbounds i8, i8* %[[BITCAST3]], i64 12 -// CHECK: %[[BITCAST4:[0-9]+]] = bitcast i8* %[[GEP_DERIVED]] to %class.{{.*}}.second_base* -// CHECK: %[[GEP_E:[a-zA-Z0-9]+]] = getelementptr inbounds %class.{{.*}}.second_base, %class.{{.*}}.second_base* %[[BITCAST4]], i32 0, i32 0 -// CHECK: %[[LOAD_E:[0-9]+]] = load i32, i32* %[[ARG_E]], align 4 -// CHECK: store i32 %[[LOAD_E]], i32* %[[GEP_E]], align 4 +// CHECK: %[[LOCAL_OBJECT:[a-zA-Z0-9_.]+]] = alloca %struct.{{.*}}.derived, align 8 +// CHECK: store i32 %_arg_a, i32* %[[ARG_A]], align 4 + +// Initialize 'base' subobject +// CHECK: %[[DERIVED_TO_BASE:.*]] = bitcast %struct.{{.*}}.derived* %[[LOCAL_OBJECT]] to %struct.{{.*}}.base* +// CHECK: %[[BASE_TO_PTR:.*]] = bitcast %struct.{{.*}}.base* %[[DERIVED_TO_BASE]] to i8* +// CHECK: %[[PARAM_TO_PTR:.*]] = bitcast %struct.{{.*}}.base* %_arg__base to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[BASE_TO_PTR]], i8* align 4 %[[PARAM_TO_PTR]], i64 12, i1 false) + +// Initialize 'second_base' subobject +// First, derived-to-base cast with offset: +// CHECK: %[[DERIVED_PTR:.*]] = bitcast %struct.{{.*}}.derived* %[[LOCAL_OBJECT]] to i8* +// CHECK: %[[OFFSET_CALC:.*]] = getelementptr inbounds i8, i8* %[[DERIVED_PTR]], i64 16 +// CHECK: %[[TO_SECOND_BASE:.*]] = bitcast i8* %[[OFFSET_CALC]] to %class.{{.*}}.second_base* +// Initialize 'second_base::e' +// CHECK: %[[SECOND_BASE_PTR:.*]] = getelementptr inbounds %class.{{.*}}.second_base, %class.{{.*}}.second_base* %[[TO_SECOND_BASE]], i32 0, i32 0 +// CHECK: %[[PTR_TO_WRAPPER:.*]] = getelementptr inbounds %struct.{{.*}}.__wrapper_class, %struct.{{.*}}.__wrapper_class* %_arg_e, i32 0, i32 0 +// CHECK: %[[LOAD_PTR:.*]] = load i32 addrspace(1)*, i32 addrspace(1)** %[[PTR_TO_WRAPPER]] +// CHECK: %[[AS_CAST:.*]] = addrspacecast i32 addrspace(1)* %[[LOAD_PTR]] to i32 addrspace(4)* +// CHECK: store i32 addrspace(4)* %[[AS_CAST]], i32 addrspace(4)** %[[SECOND_BASE_PTR]] // Initialize field 'a' -// CHECK: %[[GEP_A:[a-zA-Z0-9]+]] = getelementptr inbounds %struct.{{.*}}.derived, %struct.{{.*}}.derived* %[[LOCAL_OBJECT]], i32 0, i32 2 +// CHECK: %[[GEP_A:[a-zA-Z0-9]+]] = getelementptr inbounds %struct.{{.*}}.derived, %struct.{{.*}}.derived* %[[LOCAL_OBJECT]], i32 0, i32 3 // CHECK: %[[LOAD_A:[0-9]+]] = load i32, i32* %[[ARG_A]], align 4 -// CHECK: store i32 %[[LOAD_A]], i32* %[[GEP_A]], align 4 +// CHECK: store i32 %[[LOAD_A]], i32* %[[GEP_A]] diff --git a/clang/test/CodeGenSYCL/integration_header.cpp b/clang/test/CodeGenSYCL/integration_header.cpp index 146baeba4f74e..5bc45080d4235 100644 --- a/clang/test/CodeGenSYCL/integration_header.cpp +++ b/clang/test/CodeGenSYCL/integration_header.cpp @@ -28,21 +28,20 @@ // CHECK-NEXT: const kernel_param_desc_t kernel_signatures[] = { // CHECK-NEXT: //--- _ZTSZ4mainE12first_kernel // CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 1, 4 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 8, 4 }, // CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 12 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 6112, 28 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_sampler, 8, 48 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 6112, 24 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_sampler, 8, 40 }, // CHECK-EMPTY: // CHECK-NEXT: //--- _ZTSN16second_namespace13second_kernelIcEE // CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 }, // CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 6112, 4 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_sampler, 8, 24 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_sampler, 8, 16 }, // CHECK-EMPTY: // CHECK-NEXT: //--- _ZTS12third_kernelILi1Ei5pointIZ4mainE1XEE // CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 }, // CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 6112, 4 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_sampler, 8, 24 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_sampler, 8, 16 }, // CHECK-EMPTY: // CHECK-NEXT: //--- _ZTS13fourth_kernelIJN15template_arg_ns14namespaced_argILi1EEEEE // CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 }, @@ -52,11 +51,11 @@ // CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 }, // CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 4 }, // CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 8 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 24 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 28 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 44 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 48 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 64 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 20 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 24 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 36 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 40 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 52 }, // CHECK-EMPTY: // CHECK-NEXT: }; // diff --git a/clang/test/CodeGenSYCL/kernel-param-acc-array-ih.cpp b/clang/test/CodeGenSYCL/kernel-param-acc-array-ih.cpp index 8d2fda59c68c7..88a210ffa74d3 100644 --- a/clang/test/CodeGenSYCL/kernel-param-acc-array-ih.cpp +++ b/clang/test/CodeGenSYCL/kernel-param-acc-array-ih.cpp @@ -21,15 +21,10 @@ // CHECK-NEXT: const kernel_param_desc_t kernel_signatures[] = { // CHECK-NEXT: //--- _ZTSZ4mainE8kernel_A // CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 0 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 16 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 12 }, // CHECK-EMPTY: // CHECK-NEXT: }; -// CHECK: static constexpr -// CHECK-NEXT: const unsigned kernel_signature_start[] = { -// CHECK-NEXT: 0 // _ZTSZ4mainE8kernel_A -// CHECK-NEXT: }; - // CHECK: template <> struct KernelInfo { #include "Inputs/sycl.hpp" diff --git a/clang/test/CodeGenSYCL/kernel-param-member-acc-array-ih.cpp b/clang/test/CodeGenSYCL/kernel-param-member-acc-array-ih.cpp index 8175b78d95c1f..43889ab88ff6e 100644 --- a/clang/test/CodeGenSYCL/kernel-param-member-acc-array-ih.cpp +++ b/clang/test/CodeGenSYCL/kernel-param-member-acc-array-ih.cpp @@ -21,15 +21,10 @@ // CHECK-NEXT: const kernel_param_desc_t kernel_signatures[] = { // CHECK-NEXT: //--- _ZTSZ4mainE8kernel_C // CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 0 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 16 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 12 }, // CHECK-EMPTY: // CHECK-NEXT: }; -// CHECK: static constexpr -// CHECK-NEXT: const unsigned kernel_signature_start[] = { -// CHECK-NEXT: 0 // _ZTSZ4mainE8kernel_C -// CHECK-NEXT: }; - // CHECK: template <> struct KernelInfo { #include "Inputs/sycl.hpp" diff --git a/clang/test/CodeGenSYCL/kernel-param-pod-array-ih.cpp b/clang/test/CodeGenSYCL/kernel-param-pod-array-ih.cpp index ad2b36524a78e..79e241adab6d0 100644 --- a/clang/test/CodeGenSYCL/kernel-param-pod-array-ih.cpp +++ b/clang/test/CodeGenSYCL/kernel-param-pod-array-ih.cpp @@ -21,43 +21,16 @@ // CHECK: static constexpr // CHECK-NEXT: const kernel_param_desc_t kernel_signatures[] = { // CHECK-NEXT: //--- _ZTSZ4mainE8kernel_B -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 4 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 16 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 20, 0 }, // CHECK-EMPTY: // CHECK-NEXT: //--- _ZTSZ4mainE8kernel_C -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 4 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 16 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 20 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 24, 0 }, // CHECK-EMPTY: // CHECK-NEXT: //--- _ZTSZ4mainE8kernel_D -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 4 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 16 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 20 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 24 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 28 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 32 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 36 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 40 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 44 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 48, 0 }, // CHECK-EMPTY: // CHECK-NEXT: }; -// CHECK: static constexpr -// CHECK-NEXT: const unsigned kernel_signature_start[] = { -// CHECK-NEXT: 0, // _ZTSZ4mainE8kernel_B -// CHECK-NEXT: 6, // _ZTSZ4mainE8kernel_C -// CHECK-NEXT: 13 // _ZTSZ4mainE8kernel_D -// CHECK-NEXT: }; - // CHECK: template <> struct KernelInfo { // CHECK: template <> struct KernelInfo { // CHECK: template <> struct KernelInfo { diff --git a/clang/test/CodeGenSYCL/kernel-param-pod-array.cpp b/clang/test/CodeGenSYCL/kernel-param-pod-array.cpp index 26b28a4a58cf6..c9f602261a8f7 100644 --- a/clang/test/CodeGenSYCL/kernel-param-pod-array.cpp +++ b/clang/test/CodeGenSYCL/kernel-param-pod-array.cpp @@ -46,136 +46,87 @@ int main() { // Check kernel_B parameters // CHECK: define spir_kernel void @{{.*}}kernel_B -// CHECK-SAME: i32 [[ELEM_ARG0:%[a-zA-Z0-9_]+]], -// CHECK-SAME: i32 [[ELEM_ARG1:%[a-zA-Z_]+_[0-9]+]]) +// CHECK-SAME:(%struct.{{.*}}.__wrapper_class* byval(%struct.{{.*}}.__wrapper_class) align 4 %[[ARR_ARG:.*]]) // Check local lambda object alloca -// CHECK: [[LOCAL_OBJECT:%[0-9]+]] = alloca %"class.{{.*}}.anon", align 4 - -// Check local variables created for parameters -// CHECK: store i32 [[ELEM_ARG0]], i32* [[ELEM_L0:%[a-zA-Z_]+.addr]], align 4 -// CHECK: store i32 [[ELEM_ARG1]], i32* [[ELEM_L1:%[a-zA-Z_]+.addr[0-9]*]], align 4 - -// Check init of local array -// CHECK: [[ARRAY:%[0-9]*]] = getelementptr inbounds %"class.{{.*}}.anon", %"class.{{.*}}.anon"* [[LOCAL_OBJECT]], i32 0, i32 0 -// CHECK: [[ARRAY_BEGIN:%[a-zA-Z_.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* [[ARRAY]], i64 0, i64 0 -// CHECK: [[ARRAY0:%[0-9]*]] = load i32, i32* [[ELEM_L0]], align 4 -// CHECK: store i32 [[ARRAY0]], i32* [[ARRAY_BEGIN]], align 4 -// CHECK: [[ARRAY_ELEMENT:%[a-zA-Z_.]+]] = getelementptr inbounds i32, i32* %arrayinit.begin, i64 1 -// CHECK: [[ARRAY1:%[0-9]*]] = load i32, i32* [[ELEM_L1]], align 4 -// CHECK: store i32 [[ARRAY1]], i32* [[ARRAY_ELEMENT]], align 4 +// CHECK: %[[LOCAL_OBJECT:[0-9]+]] = alloca %"class.{{.*}}.anon", align 4 + +// Check for Array init loop +// CHECK: %[[LAMBDA_PTR:.+]] = getelementptr inbounds %"class.{{.*}}.anon", %"class.{{.*}}.anon"* %[[LOCAL_OBJECT]], i32 0, i32 0 +// CHECK: %[[WRAPPER_PTR:.+]] = getelementptr inbounds %struct.{{.*}}.__wrapper_class, %struct.{{.*}}.__wrapper_class* %[[ARR_ARG]], i32 0, i32 0 +// CHECK: %[[ARRAY_BEGIN:.+]] = getelementptr inbounds [2 x i32], [2 x i32]* %[[LAMBDA_PTR]], i64 0, i64 0 +// CHECK: br label %[[ARRAYINITBODY:.+]] + +// The loop body itself +// CHECK: [[ARRAYINITBODY]]: +// CHECK: %[[ARRAYINDEX:.+]] = phi i64 [ 0, %{{.*}} ], [ %[[NEXTINDEX:.+]], %[[ARRAYINITBODY]] ] +// CHECK: %[[TARG_ARRAY_ELEM:.+]] = getelementptr inbounds i32, i32* %[[ARRAY_BEGIN]], i64 %[[ARRAYINDEX]] +// CHECK: %[[SRC_ELEM:.+]] = getelementptr inbounds [2 x i32], [2 x i32]* %[[WRAPPER_PTR]], i64 0, i64 %[[ARRAYINDEX]] +// CHECK: %[[SRC_VAL:.+]] = load i32, i32* %[[SRC_ELEM]] +// CHECK: store i32 %[[SRC_VAL]], i32* %[[TARG_ARRAY_ELEM]] +// CHECK: %[[NEXTINDEX]] = add nuw i64 %[[ARRAYINDEX]], 1 +// CHECK: %[[ISDONE:.+]] = icmp eq i64 %[[NEXTINDEX]], 2 +// CHECK: br i1 %[[ISDONE]], label %{{.*}}, label %[[ARRAYINITBODY]] // Check kernel_C parameters // CHECK: define spir_kernel void @{{.*}}kernel_C -// CHECK-SAME: i32 [[FOO1_A:%[a-zA-Z0-9_]+]], i32 [[FOO1_B1_X:%[a-zA-Z0-9_]+]], i32 [[FOO1_B1_Y:%[a-zA-Z0-9_]+]], i32 [[FOO1_B2_X:%[a-zA-Z0-9_]+]], i32 [[FOO1_B2_Y:%[a-zA-Z0-9_]+]], i32 [[FOO1_C:%[a-zA-Z0-9_]+]], -// CHECK-SAME: i32 [[FOO2_A:%[a-zA-Z0-9_]+]], i32 [[FOO2_B1_X:%[a-zA-Z0-9_]+]], i32 [[FOO2_B1_Y:%[a-zA-Z0-9_]+]], i32 [[FOO2_B2_X:%[a-zA-Z0-9_]+]], i32 [[FOO2_B2_Y:%[a-zA-Z0-9_]+]], i32 [[FOO2_C:%[a-zA-Z0-9_]+]] +// CHECK-SAME:(%struct.{{.*}}.__wrapper_class{{.*}}* byval(%struct.{{.*}}.__wrapper_class{{.*}}) align 4 %[[ARR_ARG:.*]]) // Check local lambda object alloca -// CHECK: [[KERNEL_OBJ:%[0-9]+]] = alloca %"class.{{.*}}.anon.0", align 4 - -// Check local stores -// CHECK: store i32 [[FOO1_A]], i32* [[FOO1_A_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO1_B1_X]], i32* [[FOO1_B1_X_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO1_B1_Y]], i32* [[FOO1_B1_Y_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO1_B2_X]], i32* [[FOO1_B2_X_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO1_B2_Y]], i32* [[FOO1_B2_Y_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO1_C]], i32* [[FOO1_C_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO2_A]], i32* [[FOO2_A_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO2_B1_X]], i32* [[FOO2_B1_X_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO2_B1_Y]], i32* [[FOO2_B1_Y_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO2_B2_X]], i32* [[FOO2_B2_X_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO2_B2_Y]], i32* [[FOO2_B2_Y_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[FOO2_C]], i32* [[FOO2_C_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 - -// Check initialization of local array - -// Initialize struct_array[0].foo_a -// CHECK: [[GEP:%[a-zA-Z0-9_]+]] = getelementptr inbounds %"class.{{.*}}.anon.0", %"class.{{.*}}.anon.0"* [[KERNEL_OBJ]], i32 0, i32 0 -// CHECK: [[FOO_ARRAY_0:%[a-zA-Z_.]+]] = getelementptr inbounds [2 x %struct.{{.*}}.foo], [2 x %struct.{{.*}}.foo]* [[GEP]], i64 0, i64 0 -// CHECK: [[GEP_FOO1_A:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}.foo, %struct.{{.*}}.foo* [[FOO_ARRAY_0]], i32 0, i32 0 -// CHECK: [[LOAD_FOO1_A:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO1_A_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO1_A]], i32* [[GEP_FOO1_A]], align 4 - -// Initialize struct_array[0].foo_b[0].x -// CHECK: [[GEP_FOO1_B:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}.foo, %struct.{{.*}}.foo* [[FOO_ARRAY_0]], i32 0, i32 1 -// CHECK: [[B_ARRAY_0:%[a-zA-Z0-9_.]+]] = getelementptr inbounds [2 x %struct.{{.*}}foo_inner.foo_inner], [2 x %struct.{{.*}}foo_inner.foo_inner]* [[GEP_FOO1_B]], i64 0, i64 0 -// CHECK: [[GEP_FOO1_B1_X:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[B_ARRAY_0]], i32 0, i32 0 -// CHECK: [[LOAD_FOO1_B1_X:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO1_B1_X_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO1_B1_X]], i32* [[GEP_FOO1_B1_X]], align 4 - -// Initialize struct_array[0].foo_b[0].y -// CHECK: [[GEP_FOO1_B1_Y:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[B_ARRAY_0]], i32 0, i32 1 -// CHECK: [[LOAD_FOO1_B1_Y:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO1_B1_Y_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO1_B1_Y]], i32* [[GEP_FOO1_B1_Y]], align 4 - -// Initialize struct_array[0].foo_b[1].x -// CHECK: [[B_ARRAY_1:%[a-zA-Z0-9_.]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[B_ARRAY_0]], i64 1 -// CHECK: [[GEP_FOO1_B2_X:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[B_ARRAY_1]], i32 0, i32 0 -// CHECK: [[LOAD_FOO1_B2_X:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO1_B2_X_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO1_B2_X]], i32* [[GEP_FOO1_B2_X]], align 4 - -// Initialize struct_array[0].foo_b[1].y -// CHECK: [[GEP_FOO1_B2_Y:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[B_ARRAY_1]], i32 0, i32 1 -// CHECK: [[LOAD_FOO1_B2_Y:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO1_B2_Y_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO1_B2_Y]], i32* [[GEP_FOO1_B2_Y]], align 4 - -// Initialize struct_array[0].foo_c -// CHECK: [[GEP_FOO1_C:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo.foo, %struct.{{.*}}foo.foo* [[FOO_ARRAY_0]], i32 0, i32 2 -// CHECK: [[LOAD_FOO1_C:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO1_C_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO1_C]], i32* [[GEP_FOO1_C]], align 4 - -// Initialize struct_array[1].foo_a -// CHECK: [[FOO_ARRAY_1:%[a-zA-Z0-9_.]+]] = getelementptr inbounds %struct._ZTS3foo.foo, %struct._ZTS3foo.foo* [[FOO_ARRAY_0]], i64 1 -// CHECK: [[GEP_FOO2_A:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo.foo, %struct.{{.*}}foo.foo* [[FOO_ARRAY_1]], i32 0, i32 0 -// CHECK: [[LOAD_FOO2_A:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO2_A_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO2_A]], i32* [[GEP_FOO2_A]], align 4 - -// Initialize struct_array[1].foo_b[0].x -// CHECK: [[GEP_FOO2_B:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}.foo, %struct.{{.*}}.foo* [[FOO_ARRAY_1]], i32 0, i32 1 -// CHECK: [[FOO2_B_ARRAY_0:%[a-zA-Z0-9_.]+]] = getelementptr inbounds [2 x %struct.{{.*}}foo_inner.foo_inner], [2 x %struct.{{.*}}foo_inner.foo_inner]* [[GEP_FOO2_B]], i64 0, i64 0 -// CHECK: [[GEP_FOO2_B1_X:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[FOO2_B_ARRAY_0]], i32 0, i32 0 -// CHECK: [[LOAD_FOO2_B1_X:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO2_B1_X_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO2_B1_X]], i32* [[GEP_FOO2_B1_X]] - -// Initialize struct_array[1].foo_b[0].y -// CHECK: [[GEP_FOO2_B1_Y:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[FOO2_B_ARRAY_0]], i32 0, i32 1 -// CHECK: [[LOAD_FOO2_B1_Y:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO2_B1_Y_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO2_B1_Y]], i32* [[GEP_FOO2_B1_Y]], align 4 - -// Initialize struct_array[1].foo_b[1].x -// CHECK: [[FOO2_B_ARRAY_1:%[a-zA-Z0-9_.]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[FOO2_B_ARRAY_0]], i64 1 -// CHECK: [[GEP_FOO2_B2_X:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[FOO2_B_ARRAY_1]], i32 0, i32 0 -// CHECK: [[LOAD_FOO2_B2_X:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO2_B2_X_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO2_B2_X]], i32* [[GEP_FOO2_B2_X]], align 4 - -// Initialize struct_array[1].foo_b[1].y -// CHECK: [[GEP_FOO2_B2_Y:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo_inner.foo_inner, %struct.{{.*}}foo_inner.foo_inner* [[FOO2_B_ARRAY_1]], i32 0, i32 1 -// CHECK: [[LOAD_FOO2_B2_Y:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO2_B2_Y_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO2_B2_Y]], i32* [[GEP_FOO2_B2_Y]], align 4 - -// Initialize struct_array[1].foo_c -// CHECK: [[GEP_FOO2_C:%[a-zA-Z0-9_]+]] = getelementptr inbounds %struct.{{.*}}foo.foo, %struct.{{.*}}foo.foo* [[FOO_ARRAY_1]], i32 0, i32 2 -// CHECK: [[LOAD_FOO2_C:%[a-zA-Z0-9_]+]] = load i32, i32* [[FOO2_C_LOCAL]], align 4 -// CHECK: store i32 [[LOAD_FOO2_C]], i32* [[GEP_FOO2_C]], align 4 +// CHECK: %[[LOCAL_OBJECT:[0-9]+]] = alloca %"class.{{.*}}.anon{{.*}}", align 4 + +// Check for Array init loop +// CHECK: %[[LAMBDA_PTR:.+]] = getelementptr inbounds %"class.{{.*}}.anon{{.*}}", %"class.{{.*}}.anon{{.*}}"* %[[LOCAL_OBJECT]], i32 0, i32 0 +// CHECK: %[[WRAPPER_PTR:.+]] = getelementptr inbounds %struct.{{.*}}.__wrapper_class{{.*}}, %struct.{{.*}}.__wrapper_class{{.*}}* %[[ARR_ARG]], i32 0, i32 0 +// CHECK: %[[ARRAY_BEGIN:.+]] = getelementptr inbounds [2 x %struct.{{.*}}.foo], [2 x %struct.{{.*}}.foo]* %[[LAMBDA_PTR]], i64 0, i64 0 +// CHECK: br label %[[ARRAYINITBODY:.+]] + +// The loop body itself +// CHECK: [[ARRAYINITBODY]]: +// CHECK: %[[ARRAYINDEX:.+]] = phi i64 [ 0, %{{.*}} ], [ %[[NEXTINDEX:.+]], %[[ARRAYINITBODY]] ] +// CHECK: %[[TARG_ARRAY_ELEM:.+]] = getelementptr inbounds %struct.{{.*}}.foo, %struct.{{.*}}.foo* %[[ARRAY_BEGIN]], i64 %[[ARRAYINDEX]] +// CHECK: %[[SRC_ELEM:.+]] = getelementptr inbounds [2 x %struct.{{.*}}.foo], [2 x %struct.{{.*}}.foo]* %[[WRAPPER_PTR]], i64 0, i64 %[[ARRAYINDEX]] +// CHECK: %[[TARG_PTR:.+]] = bitcast %struct.{{.*}}.foo* %[[TARG_ARRAY_ELEM]] to i8* +// CHECK: %[[SRC_PTR:.+]] = bitcast %struct.{{.*}}.foo* %[[SRC_ELEM]] to i8* +// call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %[[TARG_PTR]], i8* align %[[SRC_PTR]], i64 24, i1 false) +// CHECK: %[[NEXTINDEX]] = add nuw i64 %[[ARRAYINDEX]], 1 +// CHECK: %[[ISDONE:.+]] = icmp eq i64 %[[NEXTINDEX]], 2 +// CHECK: br i1 %[[ISDONE]], label %{{.*}}, label %[[ARRAYINITBODY]] // Check kernel_D parameters // CHECK: define spir_kernel void @{{.*}}kernel_D -// CHECK-SAME: i32 [[ARR_2D_1:%[a-zA-Z0-9_]+]], i32 [[ARR_2D_2:%[a-zA-Z0-9_]+]] +// CHECK-SAME:(%struct.{{.*}}.__wrapper_class{{.*}}* byval(%struct.{{.*}}.__wrapper_class{{.*}}) align 4 %[[ARR_ARG:.*]]) // Check local lambda object alloca -// CHECK: [[LAMBDA_OBJ:%[0-9]+]] = alloca %"class.{{.*}}.anon.1", align 4 - -// Check local stores -// CHECK: store i32 [[ARR_2D_1]], i32* [[ARR_2D_1_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 -// CHECK: store i32 [[ARR_2D_2]], i32* [[ARR_2D_2_LOCAL:%[a-zA-Z_]+.addr[0-9]*]], align 4 - -// Check initialization of local array -// CHECK: [[GEP_ARR_2D:%[0-9]*]] = getelementptr inbounds %"class._ZTSZ4mainE3$_0.anon.1", %"class._ZTSZ4mainE3$_0.anon.1"* [[LAMBDA_OBJ]], i32 0, i32 0 -// CHECK: [[GEP_ARR_BEGIN1:%[a-zA-Z0-9_.]+]] = getelementptr inbounds [2 x [1 x i32]], [2 x [1 x i32]]* [[GEP_ARR_2D]], i64 0, i64 0 -// CHECK: [[GEP_ARR_ELEM0:%[a-zA-Z0-9_.]+]] = getelementptr inbounds [1 x i32], [1 x i32]* [[GEP_ARR_BEGIN1]], i64 0, i64 0 -// CHECK: [[ARR_2D_ELEM0:%[0-9]*]] = load i32, i32* [[ARR_2D_1_LOCAL]], align 4 -// CHECK: store i32 [[ARR_2D_ELEM0]], i32* [[GEP_ARR_ELEM0]], align 4 -// CHECK: [[GEP_ARR_BEGIN2:%[a-zA-Z_.]+]] = getelementptr inbounds [1 x i32], [1 x i32]* [[GEP_ARR_BEGIN1]], i64 1 -// CHECK: [[GEP_ARR_ELEM1:%[a-zA-Z0-9_.]+]] = getelementptr inbounds [1 x i32], [1 x i32]* [[GEP_ARR_BEGIN2]], i64 0, i64 0 -// CHECK: [[ARR_2D_ELEM1:%[0-9]*]] = load i32, i32* [[ARR_2D_2_LOCAL]], align 4 -// CHECK: store i32 [[ARR_2D_ELEM1]], i32* [[GEP_ARR_ELEM1]], align 4 +// CHECK: %[[LOCAL_OBJECT:[0-9]+]] = alloca %"class.{{.*}}.anon{{.*}}", align 4 + +// Check for Array init loop +// CHECK: %[[LAMBDA_PTR:.+]] = getelementptr inbounds %"class.{{.*}}.anon{{.*}}", %"class.{{.*}}.anon{{.*}}"* %[[LOCAL_OBJECT]], i32 0, i32 0 +// CHECK: %[[WRAPPER_PTR:.+]] = getelementptr inbounds %struct.{{.*}}.__wrapper_class{{.*}}, %struct.{{.*}}.__wrapper_class{{.*}}* %[[ARR_ARG]], i32 0, i32 0 +// CHECK: %[[ARRAY_BEGIN:.+]] = getelementptr inbounds [2 x [1 x i32]], [2 x [1 x i32]]* %[[LAMBDA_PTR]], i64 0, i64 0 +// CHECK: br label %[[ARRAYINITBODY:.+]] + +// Check Outer loop. +// CHECK: [[ARRAYINITBODY]]: +// CHECK: %[[ARRAYINDEX:.+]] = phi i64 [ 0, %{{.*}} ], [ %[[NEXTINDEX:.+]], %[[ARRAYINITEND:.+]] ] +// CHECK: %[[TARG_OUTER_ELEM:.+]] = getelementptr inbounds [1 x i32], [1 x i32]* %[[ARRAY_BEGIN]], i64 %[[ARRAYINDEX]] +// CHECK: %[[SRC_OUTER_ELEM:.+]] = getelementptr inbounds [2 x [1 x i32]], [2 x [1 x i32]]* %[[WRAPPER_PTR]], i64 0, i64 %[[ARRAYINDEX]] +// CHECK: %[[ARRAY_BEGIN_INNER:.+]] = getelementptr inbounds [1 x i32], [1 x i32]* %[[TARG_OUTER_ELEM]], i64 0, i64 0 +// CHECK: br label %[[ARRAYINITBODY_INNER:.+]] + +// Check Inner Loop +// CHECK: [[ARRAYINITBODY_INNER]]: +// CHECK: %[[ARRAYINDEX_INNER:.+]] = phi i64 [ 0, %{{.*}} ], [ %[[NEXTINDEX_INNER:.+]], %[[ARRAYINITBODY_INNER:.+]] ] +// CHECK: %[[TARG_INNER_ELEM:.+]] = getelementptr inbounds i32, i32* %[[ARRAY_BEGIN_INNER]], i64 %[[ARRAYINDEX_INNER]] +// CHECK: %[[SRC_INNER_ELEM:.+]] = getelementptr inbounds [1 x i32], [1 x i32]* %[[SRC_OUTER_ELEM]], i64 0, i64 %[[ARRAYINDEX_INNER]] +// CHECK: %[[SRC_LOAD:.+]] = load i32, i32* %[[SRC_INNER_ELEM]] +// CHECK: store i32 %[[SRC_LOAD]], i32* %[[TARG_INNER_ELEM]] +// CHECK: %[[NEXTINDEX_INNER]] = add nuw i64 %[[ARRAYINDEX_INNER]], 1 +// CHECK: %[[ISDONE_INNER:.+]] = icmp eq i64 %[[NEXTINDEX_INNER]], 1 +// CHECK: br i1 %[[ISDONE_INNER]], label %[[ARRAYINITEND]], label %[[ARRAYINITBODY_INNER]] + +// Check Inner loop 'end' +// CHECK: [[ARRAYINITEND]]: +// CHECK: %[[NEXTINDEX]] = add nuw i64 %[[ARRAYINDEX]], 1 +// CHECK: %[[ISDONE:.+]] = icmp eq i64 %[[NEXTINDEX]], 2 +// CHECK: br i1 %[[ISDONE]], label %{{.*}}, label %[[ARRAYINITBODY]] diff --git a/clang/test/CodeGenSYCL/num-simd-work-items.cpp b/clang/test/CodeGenSYCL/num-simd-work-items.cpp index 5613969b88a91..b88cfbf5ff917 100644 --- a/clang/test/CodeGenSYCL/num-simd-work-items.cpp +++ b/clang/test/CodeGenSYCL/num-simd-work-items.cpp @@ -5,6 +5,12 @@ class Foo { [[intelfpga::num_simd_work_items(1)]] void operator()() const {} }; +template +class Functor { +public: + [[intelfpga::num_simd_work_items(SIZE)]] void operator()() const {} +}; + template __attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) { kernelFunc(); @@ -17,10 +23,13 @@ void bar() { kernel( []() [[intelfpga::num_simd_work_items(42)]] {}); + Functor<2> f; + kernel(f); } // CHECK: define spir_kernel void @{{.*}}kernel_name1() {{.*}} !num_simd_work_items ![[NUM1:[0-9]+]] // CHECK: define spir_kernel void @{{.*}}kernel_name2() {{.*}} !num_simd_work_items ![[NUM42:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name3() {{.*}} !num_simd_work_items ![[NUM2:[0-9]+]] // CHECK: ![[NUM1]] = !{i32 1} // CHECK: ![[NUM42]] = !{i32 42} - +// CHECK: ![[NUM2]] = !{i32 2} diff --git a/clang/test/CodeGenSYCL/stdtypes_kernel_type.cpp b/clang/test/CodeGenSYCL/stdtypes_kernel_type.cpp new file mode 100644 index 0000000000000..04eeb22b94f66 --- /dev/null +++ b/clang/test/CodeGenSYCL/stdtypes_kernel_type.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-int-header=%t.h -DCHECK_ERROR -verify %s +// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -fsycl-int-header=%t.h %s +// RUN: FileCheck -input-file=%t.h %s +// +// CHECK: #include +// CHECK-NEXT: #include +// +// CHECK: static constexpr +// CHECK-NEXT: const char* const kernel_names[] = { +// CHECK-NEXT: "_ZTSm", +// CHECK-NEXT: "_ZTSl" +// CHECK-NEXT: }; +// +// CHECK: static constexpr +// CHECK-NEXT: const kernel_param_desc_t kernel_signatures[] = { +// CHECK-NEXT: //--- _ZTSm +// CHECK-EMPTY: +// CHECK-NEXT: //--- _ZTSl +// CHECK-EMPTY: +// CHECK-NEXT: }; + +// CHECK: template <> struct KernelInfo { +// CHECK: template <> struct KernelInfo { + +void usage() { +} + +namespace std { +typedef long unsigned int size_t; +typedef long int ptrdiff_t; +typedef decltype(nullptr) nullptr_t; +class T; +class U; +} // namespace std + +template +struct Templated_kernel_name; + +template +__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { + kernelFunc(); +} + +int main() { +#ifdef CHECK_ERROR + kernel_single_task([=]() {}); // expected-error {{kernel name cannot be a type in the "std" namespace}} + kernel_single_task([=]() {}); // expected-error {{kernel name cannot be a type in the "std" namespace}} + kernel_single_task>([=]() {}); // expected-error {{kernel name cannot be a type in the "std" namespace}} + kernel_single_task>([=]() {}); // expected-error {{kernel name cannot be a type in the "std" namespace}} +#endif + + // Although in the std namespace, these resolve to builtins such as `int` that are allowed in kernel names + kernel_single_task([=]() {}); + kernel_single_task([=]() {}); + + return 0; +} diff --git a/clang/test/CodeGenSYCL/struct_kernel_param.cpp b/clang/test/CodeGenSYCL/struct_kernel_param.cpp index 12a27dc6f2c87..11c1526f41040 100644 --- a/clang/test/CodeGenSYCL/struct_kernel_param.cpp +++ b/clang/test/CodeGenSYCL/struct_kernel_param.cpp @@ -3,13 +3,16 @@ // CHECK: const kernel_param_desc_t kernel_signatures[] = { // CHECK-NEXT: //--- _ZTSZZ5test0vENK3$_0clERN2cl4sycl7handlerEE8MyKernel +// Accessor // CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 0 }, +// FldInt, offset to 16 because the float* causes the alignment of the structs +// to change. // CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 16 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 20 }, +// FldArr // CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 24 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 28 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 32 }, -// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 36 }, +// FldFloat +// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 8, 32 }, +// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 12, 40 }, // CHECK-EMPTY: // CHECK-NEXT:}; @@ -21,7 +24,7 @@ using namespace cl::sycl; struct MyNestedStruct { int FldArr[1]; - float FldFloat; + float *FldFloat; }; struct MyStruct { diff --git a/clang/test/CodeGenSYCL/sycl-device-alias.cpp b/clang/test/CodeGenSYCL/sycl-device-alias.cpp new file mode 100644 index 0000000000000..3a124901b471d --- /dev/null +++ b/clang/test/CodeGenSYCL/sycl-device-alias.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s +// Test that aliasing does not force an unused entity to be emitted + +// CHECK-NOT: define spir_func void @unused_func() +extern "C" void unused_func() {} +// CHECK-NOT: @unused_aliaser +extern "C" void unused_aliaser() __attribute__((alias("unused_func"))); +// CHECK-NOT: @unused_int +int unused_int = 3; +// CHECK-NOT: @alias_unused_int +extern int alias_unused_int __attribute__((alias("unused_int"))); + +// CHECK-DAG: define spir_func void @used_func() +extern "C" void used_func() {} +// CHECK-DAG: @aliaser = alias void (), void ()* @used_func +extern "C" void aliaser() __attribute__((alias("used_func"))); + +// CHECK-DAG: define spir_func void @func() +extern "C" void func() {} +// CHECK-DAG: @used_aliaser = alias void (), void ()* @func +extern "C" void used_aliaser() __attribute__((alias("func"))); + +// CHECK-DAG: @used_int = addrspace(1) constant i32 5, align 4 +extern "C" const int used_int = 5; +// CHECK-DAG: @alias_used_int = alias i32, i32 addrspace(1)* @used_int +extern "C" const int alias_used_int __attribute__((alias("used_int"))); +// CHECK-DAG: @vint = addrspace(1) constant i32 7, align 4 +extern "C" const int vint = 7; +// CHECK-DAG: @used_alias_used_int = alias i32, i32 addrspace(1)* @vint +extern "C" const int used_alias_used_int __attribute__((alias("vint"))); + +// CHECK-DAG: define spir_func void @{{.*}}bar{{.*}} +void bar(const int &i) {} + +// CHECK-DAG: define spir_func void @{{.*}}foo{{.*}} +void __attribute__((sycl_device)) foo() { + // CHECK-DAG: call spir_func void @{{.*}}bar{{.*}}@used_int + bar(used_int); + // CHECK-DAG: call spir_func void @{{.*}}bar{{.*}}@used_alias_used_int + bar(used_alias_used_int); + // CHECK-DAG: call spir_func void @used_func() + used_func(); + // CHECK-DAG: call spir_func void @used_aliaser() + used_aliaser(); +} diff --git a/clang/test/CodeGenSYCL/union-kernel-param-ih.cpp b/clang/test/CodeGenSYCL/union-kernel-param-ih.cpp index ed57d35a89c93..4dddedc1e5c52 100644 --- a/clang/test/CodeGenSYCL/union-kernel-param-ih.cpp +++ b/clang/test/CodeGenSYCL/union-kernel-param-ih.cpp @@ -24,11 +24,6 @@ // CHECK-EMPTY: // CHECK-NEXT:}; -// CHECK: static constexpr -// CHECK-NEXT: const unsigned kernel_signature_start[] = { -// CHECK-NEXT: 0 // _ZTSZ4mainE8kernel_A -// CHECK-NEXT: }; - // CHECK: template <> struct KernelInfo { union MyUnion { diff --git a/clang/test/CodeGenSYCL/wrapped-accessor.cpp b/clang/test/CodeGenSYCL/wrapped-accessor.cpp index d59a243d60d51..c67ae01ee1ba0 100644 --- a/clang/test/CodeGenSYCL/wrapped-accessor.cpp +++ b/clang/test/CodeGenSYCL/wrapped-accessor.cpp @@ -21,11 +21,6 @@ // CHECK-EMPTY: // CHECK-NEXT: }; -// CHECK: static constexpr -// CHECK-NEXT: const unsigned kernel_signature_start[] = { -// CHECK-NEXT: 0 // _ZTSZ4mainE14wrapped_access -// CHECK-NEXT: }; - // CHECK: template <> struct KernelInfo { #include "Inputs/sycl.hpp" diff --git a/clang/test/Driver/cl-x86-flags.c b/clang/test/Driver/cl-x86-flags.c index 595959b48828a..15e3e012f2ac1 100644 --- a/clang/test/Driver/cl-x86-flags.c +++ b/clang/test/Driver/cl-x86-flags.c @@ -128,5 +128,9 @@ // RUN: %clang_cl -m64 -arch:avx512 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx51264 %s // avx51264: argument unused during compilation +// RUN: %clang_cl -m64 -arch:AVX -tune:haswell --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=tune %s +// tune: "-target-cpu" "sandybridge" +// tune-SAME: "-tune-cpu" "haswell" + void f() { } diff --git a/clang/test/Driver/config-file3.c b/clang/test/Driver/config-file3.c index 148646c2ebbf1..fc5c286553ad5 100644 --- a/clang/test/Driver/config-file3.c +++ b/clang/test/Driver/config-file3.c @@ -1,14 +1,15 @@ // REQUIRES: shell // REQUIRES: x86-registered-target +// RUN: rm -rf %t && mkdir %t + //--- If config file is specified by relative path (workdir/cfg-s2), it is searched for by that path. + +// RUN: mkdir -p %t/workdir/subdir +// RUN: echo "@subdir/cfg-s2" > %t/workdir/cfg-1 +// RUN: echo "-Wundefined-var-template" > %t/workdir/subdir/cfg-s2 // -// RUN: mkdir -p %T/workdir -// RUN: echo "@subdir/cfg-s2" > %T/workdir/cfg-1 -// RUN: mkdir -p %T/workdir/subdir -// RUN: echo "-Wundefined-var-template" > %T/workdir/subdir/cfg-s2 -// -// RUN: ( cd %T && %clang --config workdir/cfg-1 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-REL ) +// RUN: ( cd %t && %clang --config workdir/cfg-1 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-REL ) // // CHECK-REL: Configuration file: {{.*}}/workdir/cfg-1 // CHECK-REL: -Wundefined-var-template @@ -16,12 +17,11 @@ //--- Invocation qqq-clang-g++ tries to find config file qqq-clang-g++.cfg first. // -// RUN: rm -rf %T/testdmode -// RUN: mkdir -p %T/testdmode -// RUN: ln -s %clang %T/testdmode/qqq-clang-g++ -// RUN: echo "-Wundefined-func-template" > %T/testdmode/qqq-clang-g++.cfg -// RUN: echo "-Werror" > %T/testdmode/qqq.cfg -// RUN: %T/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix FULL-NAME +// RUN: mkdir %t/testdmode +// RUN: ln -s %clang %t/testdmode/qqq-clang-g++ +// RUN: echo "-Wundefined-func-template" > %t/testdmode/qqq-clang-g++.cfg +// RUN: echo "-Werror" > %t/testdmode/qqq.cfg +// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix FULL-NAME // // FULL-NAME: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg // FULL-NAME: -Wundefined-func-template @@ -31,20 +31,20 @@ // (As the clang executable and symlink are in different directories, this // requires specifying the path via --config-*-dir= though.) // -// RUN: %T/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir=%T/testdmode -c %s -### 2>&1 | FileCheck %s -check-prefix SYMLINK +// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir=%t/testdmode -c %s -### 2>&1 | FileCheck %s -check-prefix SYMLINK // // SYMLINK: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg // //--- File specified by --config overrides config inferred from clang executable. // -// RUN: %T/testdmode/qqq-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --config i386-qqq -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-EXPLICIT +// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --config i386-qqq -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-EXPLICIT // // CHECK-EXPLICIT: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg // //--- Invocation qqq-clang-g++ tries to find config file qqq.cfg if qqq-clang-g++.cfg is not found. // -// RUN: rm %T/testdmode/qqq-clang-g++.cfg -// RUN: %T/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix SHORT-NAME +// RUN: rm %t/testdmode/qqq-clang-g++.cfg +// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix SHORT-NAME // // SHORT-NAME: Configuration file: {{.*}}/testdmode/qqq.cfg // SHORT-NAME: -Werror @@ -53,11 +53,10 @@ //--- Config files are searched for in binary directory as well. // -// RUN: rm -rf %T/testbin -// RUN: mkdir -p %T/testbin -// RUN: ln -s %clang %T/testbin/clang -// RUN: echo "-Werror" > %T/testbin/aaa.cfg -// RUN: %T/testbin/clang --config-system-dir= --config-user-dir= --config aaa.cfg -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-BIN +// RUN: mkdir %t/testbin +// RUN: ln -s %clang %t/testbin/clang +// RUN: echo "-Werror" > %t/testbin/aaa.cfg +// RUN: %t/testbin/clang --config-system-dir= --config-user-dir= --config aaa.cfg -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-BIN // // CHECK-BIN: Configuration file: {{.*}}/testbin/aaa.cfg // CHECK-BIN: -Werror @@ -68,12 +67,11 @@ //--- When reloading config file, x86_64-clang-g++ tries to find config i386-clang-g++.cfg first. // -// RUN: rm -rf %T/testreload -// RUN: mkdir -p %T/testreload -// RUN: ln -s %clang %T/testreload/x86_64-clang-g++ -// RUN: echo "-Wundefined-func-template" > %T/testreload/i386-clang-g++.cfg -// RUN: echo "-Werror" > %T/testreload/i386.cfg -// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD +// RUN: mkdir %t/testreload +// RUN: ln -s %clang %t/testreload/x86_64-clang-g++ +// RUN: echo "-Wundefined-func-template" > %t/testreload/i386-clang-g++.cfg +// RUN: echo "-Werror" > %t/testreload/i386.cfg +// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD // // CHECK-RELOAD: Configuration file: {{.*}}/testreload/i386-clang-g++.cfg // CHECK-RELOAD: -Wundefined-func-template @@ -81,24 +79,24 @@ //--- If config file is specified by --config and its name does not start with architecture, it is used without reloading. // -// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs --config-user-dir= --config config-3 -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1a +// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs --config-user-dir= --config config-3 -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1a // // CHECK-RELOAD1a: Configuration file: {{.*}}/Inputs/config-3.cfg // -// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs --config-user-dir= --config config-3 -c -target i386 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1b +// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs --config-user-dir= --config config-3 -c -target i386 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1b // // CHECK-RELOAD1b: Configuration file: {{.*}}/Inputs/config-3.cfg //--- If config file is specified by --config and its name starts with architecture, it is reloaded. // -// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --config x86_64-qqq -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1c +// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --config x86_64-qqq -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1c // // CHECK-RELOAD1c: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg //--- x86_64-clang-g++ tries to find config i386.cfg if i386-clang-g++.cfg is not found. // -// RUN: rm %T/testreload/i386-clang-g++.cfg -// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1d +// RUN: rm %t/testreload/i386-clang-g++.cfg +// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1d // // CHECK-RELOAD1d: Configuration file: {{.*}}/testreload/i386.cfg // CHECK-RELOAD1d: -Werror diff --git a/clang/test/Driver/darwin-objc-options.m b/clang/test/Driver/darwin-objc-options.m index 6684a5272175b..8721fbc1ef1e2 100644 --- a/clang/test/Driver/darwin-objc-options.m +++ b/clang/test/Driver/darwin-objc-options.m @@ -46,3 +46,12 @@ // RUN: %clang -target x86_64-linux-gnu -### %s 2>&1 | FileCheck --check-prefix=OTHER_COMPATIBILITY %s // DARWIN_COMPATIBILITY: -fcompatibility-qualified-id-block-type-checking // OTHER_COMPATIBILITY-NOT: -fcompatibility-qualified-id-block-type-checking + +// Add -fvisibility-inlines-hidden-static-local-var on Darwin. +// RUN: %clang -target x86_64-apple-darwin10 -### %s 2>&1 | FileCheck --check-prefix=DARWIN_INLINES_HIDDEN %s +// RUN: %clang -target x86_64-apple-darwin10 -fno-visibility-inlines-hidden-static-local-var -### %s 2>&1 | FileCheck --check-prefix=DARWIN_INLINES_HIDDEN_EXPLICIT_NO %s +// RUN: %clang -target x86_64-linux-gnu -### %s 2>&1 | FileCheck --check-prefix=NO_DARWIN_INLINES_HIDDEN %s +// DARWIN_INLINES_HIDDEN: -fvisibility-inlines-hidden-static-local-var +// DARWIN_INLINES_HIDDEN_EXPLICIT_NO-NOT: -fvisibility-inlines-hidden-static-local-var +// DARWIN_INLINES_HIDDEN_EXPLICIT_NO: -fno-visibility-inlines-hidden-static-local-var +// NO_DARWIN_INLINES_HIDDEN-NOT: -fvisibility-inlines-hidden-static-local-var diff --git a/clang/test/Driver/fmemprof.cpp b/clang/test/Driver/fmemprof.cpp index 049067803e2b4..a2b740e1e6e5e 100644 --- a/clang/test/Driver/fmemprof.cpp +++ b/clang/test/Driver/fmemprof.cpp @@ -1,6 +1,6 @@ -// RUN: %clangxx -target x86_64-linux-gnu -fmemprof %s -### 2>&1 | FileCheck %s -// RUN: %clangxx -target x86_64-linux-gnu -fmemprof -fno-memprof %s -### 2>&1 | FileCheck %s --check-prefix=OFF -// CHECK: "-cc1" {{.*}} "-fmemprof" +// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile %s -### 2>&1 | FileCheck %s +// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile -fno-memory-profile %s -### 2>&1 | FileCheck %s --check-prefix=OFF +// CHECK: "-cc1" {{.*}} "-fmemory-profile" // CHECK: ld{{.*}}libclang_rt.heapprof{{.*}}libclang_rt.heapprof_cxx -// OFF-NOT: "-fmemprof" +// OFF-NOT: "-fmemory-profile" // OFF-NOT: libclang_rt.heapprof diff --git a/clang/test/Driver/freebsd.c b/clang/test/Driver/freebsd.c index 769bb22da0dc7..1bf6dab802a1c 100644 --- a/clang/test/Driver/freebsd.c +++ b/clang/test/Driver/freebsd.c @@ -176,7 +176,7 @@ // RUN: %clang -mcpu=ultrasparc -target sparc64-unknown-freebsd8 %s -### -no-integrated-as 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-SPARC-CPU %s // CHECK-SPARC-CPU: cc1{{.*}}" "-target-cpu" "ultrasparc" -// CHECK-SPARC-CPU: as{{.*}}" "-Av9 +// CHECK-SPARC-CPU: as{{.*}}" "-Av9a // Check that -G flags are passed to the linker for mips // RUN: %clang -target mips-unknown-freebsd %s -### -G0 2>&1 \ diff --git a/clang/test/Driver/gcc_forward.c b/clang/test/Driver/gcc_forward.c index a99944f8f5336..e6b0670d1a027 100644 --- a/clang/test/Driver/gcc_forward.c +++ b/clang/test/Driver/gcc_forward.c @@ -1,7 +1,8 @@ // RUN: %clang -### %s -target aarch64-none-elf \ -// RUN: --coverage -e _start -fuse-ld=lld --ld-path=ld -nostdlib -r -rdynamic -static -static-pie \ +// RUN: --coverage -e _start -fuse-ld=lld --ld-path=ld -nostartfiles \ +// RUN: -nostdlib -r -rdynamic -specs=nosys.specs -static -static-pie \ // RUN: 2>&1 | FileCheck --check-prefix=FORWARD %s -// FORWARD: gcc{{[^"]*}}" "--coverage" "-fuse-ld=lld" "--ld-path=ld" "-nostdlib" "-rdynamic" "-static" "-static-pie" "-o" "a.out" "{{.*}}.o" "-e" "_start" "-r" +// FORWARD: gcc{{[^"]*}}" "--coverage" "-fuse-ld=lld" "--ld-path=ld" "-nostartfiles" "-nostdlib" "-rdynamic" "-specs=nosys.specs" "-static" "-static-pie" "-o" "a.out" "{{.*}}.o" "-e" "_start" "-r" // Check that we don't try to forward -Xclang or -mlinker-version to GCC. // PR12920 -- Check also we may not forward W_Group options to GCC. diff --git a/clang/test/Driver/linux-as.c b/clang/test/Driver/linux-as.c index 77ac05f30942c..0959bd7ba0a11 100644 --- a/clang/test/Driver/linux-as.c +++ b/clang/test/Driver/linux-as.c @@ -168,7 +168,7 @@ // RUN: | FileCheck -check-prefix=CHECK-SPARCV9 %s // CHECK-SPARCV9: as // CHECK-SPARCV9: -64 -// CHECK-SPARCV9: -Av9 +// CHECK-SPARCV9: -Av9a // CHECK-SPARCV9-NOT: -KPIC // CHECK-SPARCV9: -o // @@ -177,7 +177,7 @@ // RUN: | FileCheck -check-prefix=CHECK-SPARCV9PIC %s // CHECK-SPARCV9PIC: as // CHECK-SPARCV9PIC: -64 -// CHECK-SPARCV9PIC: -Av9 +// CHECK-SPARCV9PIC: -Av9a // CHECK-SPARCV9PIC: -KPIC // CHECK-SPARCV9PIC: -o // diff --git a/clang/test/Driver/openbsd.c b/clang/test/Driver/openbsd.c index 203b4b4a2ff0f..ae1aa64416907 100644 --- a/clang/test/Driver/openbsd.c +++ b/clang/test/Driver/openbsd.c @@ -70,7 +70,7 @@ // RUN: | FileCheck -check-prefix=CHECK-MIPS64EL-PIC %s // CHECK-AMD64-M32: as{{.*}}" "--32" // CHECK-POWERPC: as{{.*}}" "-mppc" "-many" -// CHECK-SPARC64: as{{.*}}" "-64" "-Av9" +// CHECK-SPARC64: as{{.*}}" "-64" "-Av9a" // CHECK-MIPS64: as{{.*}}" "-mabi" "64" "-EB" // CHECK-MIPS64-PIC: as{{.*}}" "-mabi" "64" "-EB" "-KPIC" // CHECK-MIPS64EL: as{{.*}}" "-mabi" "64" "-EL" diff --git a/clang/test/Driver/sycl-MD-default.cpp b/clang/test/Driver/sycl-MD-default.cpp new file mode 100644 index 0000000000000..491745289c13c --- /dev/null +++ b/clang/test/Driver/sycl-MD-default.cpp @@ -0,0 +1,23 @@ +// REQUIRES: clang-driver + +// RUN: %clang -### -fsycl -c -target x86_64-unknown-windows-msvc %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-DEFAULT %s +// RUN: %clangxx -### -fsycl -c -target x86_64-unknown-windows-msvc %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-DEFAULT %s +// CHK-DEFAULT-NOT: "-fsycl-is-device" {{.*}} "-D_MT" "-D_DLL" +// CHK-DEFAULT: "-fsycl-is-host" "-D_MT" "-D_DLL" "--dependent-lib=msvcrt{{d*}}" {{.*}} + +// RUN: %clang_cl -### -fsycl -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-DEFAULT-CL %s +// RUN: %clang_cl -### -MD -fsycl -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-DEFAULT-CL %s +// RUN: %clang_cl -### -MDd -fsycl -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-DEFAULT-CL %s +// CHK-DEFAULT-CL-NOT: "-fsycl-is-device" {{.*}} "-D_MT" "-D_DLL" +// CHK-DEFAULT-CL: "-D_MT" "-D_DLL" "--dependent-lib=msvcrt{{d*}}" {{.*}} "-fsycl-is-host" + +// RUN: %clang_cl -### -MT -fsycl -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-ERROR %s +// RUN: %clang_cl -### -MTd -fsycl -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-ERROR %s +// CHK-ERROR: option 'MT{{d*}}' unsupported with DPC++ diff --git a/clang/test/Driver/sycl-cxx-default.c b/clang/test/Driver/sycl-cxx-default.c new file mode 100644 index 0000000000000..45259da98e116 --- /dev/null +++ b/clang/test/Driver/sycl-cxx-default.c @@ -0,0 +1,19 @@ +/// When -fsycl is used, C++ source is the default +// REQUIRES: clang-driver + +// RUN: %clang -c -fsycl %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s +// RUN: %clangxx -c -fsycl %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s +// RUN: %clang_cl -c -fsycl %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s +// RUN: %clang_cl -c -fsycl /TC %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s +// RUN: %clang_cl -c -fsycl /Tc%s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s +// CXX_TYPE_CHECK: "-x" "c++" +// CXX_TYPE_CHECK-NOT: "-x" "c" + +// RUN: %clang -c -fsycl -std=c99 %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=C_SYCL_ERROR_CHECK %s +// C_SYCL_ERROR_CHECK: error: invalid argument '-std=c99' not allowed with '-fsycl diff --git a/clang/test/Driver/sycl-device-lib-win.cpp b/clang/test/Driver/sycl-device-lib-win.cpp new file mode 100644 index 0000000000000..22147a977e4c5 --- /dev/null +++ b/clang/test/Driver/sycl-device-lib-win.cpp @@ -0,0 +1,93 @@ +/// +/// Perform several driver tests for SYCL device libraries on Windows +/// +// REQUIRES: clang-driver, windows + +/// ########################################################################### + +/// test behavior of device library default link +// RUN: %clangxx -fsycl %s -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libm-fp64 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-msvc.o" "-outputs={{.*}}libsycl-msvc-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-complex.o" "-outputs={{.*}}libsycl-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-cmath.o" "-outputs={{.*}}libsycl-cmath-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cassert.o" "-outputs={{.*}}libsycl-fallback-cassert-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-complex.o" "-outputs={{.*}}libsycl-fallback-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cmath.o" "-outputs={{.*}}libsycl-fallback-cmath-{{.*}}.o" "-unbundle" + +/// ########################################################################### +/// test behavior of device library link with libm-fp64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libm-fp64 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,libm-fp64 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,libm-fp32,libm-fp64 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-msvc.o" "-outputs={{.*}}libsycl-msvc-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-complex.o" "-outputs={{.*}}libsycl-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-complex-fp64.o" "-outputs={{.*}}libsycl-complex-fp64-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-cmath.o" "-outputs={{.*}}libsycl-cmath-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-cmath-fp64.o" "-outputs={{.*}}libsycl-cmath-fp64-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cassert.o" "-outputs={{.*}}libsycl-fallback-cassert-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-complex.o" "-outputs={{.*}}libsycl-fallback-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-complex-fp64.o" "-outputs={{.*}}libsycl-fallback-complex-fp64-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cmath.o" "-outputs={{.*}}libsycl-fallback-cmath-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cmath-fp64.o" "-outputs={{.*}}libsycl-fallback-cmath-fp64-{{.*}}.o" "-unbundle" + +/// ########################################################################### + +/// test behavior of -fno-sycl-device-lib=libc +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libc -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-complex.o" "-outputs={{.*}}libsycl-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-cmath.o" "-outputs={{.*}}libsycl-cmath-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-complex.o" "-outputs={{.*}}libsycl-fallback-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cmath.o" "-outputs={{.*}}libsycl-fallback-cmath-{{.*}}.o" "-unbundle" + +/// ########################################################################### + +/// test behavior of -fno-sycl-device-lib=libm-fp32 +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBM_FP32 +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBM_FP32: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-msvc.o" "-outputs={{.*}}libsycl-msvc-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBM_FP32-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cassert.o" "-outputs={{.*}}libsycl-fallback-cassert-{{.*}}.o" "-unbundle" + +/// ########################################################################### + +/// test behavior of disabling all device libraries +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libc,libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libc,all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libm-fp32,all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libm-fp64,all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libc,all,libm-fp64,libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB: {{.*}}clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown-sycldevice" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB-NEXT: {{.*}}llvm-link{{.*}} {{.*}} "--suppress-warnings" + +/// ########################################################################### + +/// test invalid value for -f[no-]sycl-device-lib +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,dummy -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_INVALID_VALUE +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=dummy,libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_NO_DEVICE_LIB_INVALID_VALUE +// SYCL_DEVICE_LIB_INVALID_VALUE: error: unsupported argument 'dummy' to option 'fsycl-device-lib=' +// SYCL_NO_DEVICE_LIB_INVALID_VALUE: error: unsupported argument 'dummy' to option 'fno-sycl-device-lib=' diff --git a/clang/test/Driver/sycl-device-lib.cpp b/clang/test/Driver/sycl-device-lib.cpp new file mode 100644 index 0000000000000..7365d4f4948f7 --- /dev/null +++ b/clang/test/Driver/sycl-device-lib.cpp @@ -0,0 +1,93 @@ +/// +/// Perform several driver tests for SYCL device libraries on Linux +/// +// REQUIRES: clang-driver, linux + +/// ########################################################################### + +/// test behavior of device library default link +// RUN: %clangxx -fsycl %s -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libm-fp64 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-glibc.o" "-outputs={{.*}}libsycl-glibc-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-complex.o" "-outputs={{.*}}libsycl-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-cmath.o" "-outputs={{.*}}libsycl-cmath-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cassert.o" "-outputs={{.*}}libsycl-fallback-cassert-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-complex.o" "-outputs={{.*}}libsycl-fallback-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_DEFAULT-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cmath.o" "-outputs={{.*}}libsycl-fallback-cmath-{{.*}}.o" "-unbundle" + +/// ########################################################################### +/// test behavior of device library link with libm-fp64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libm-fp64 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,libm-fp64 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,libm-fp32,libm-fp64 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64 +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-glibc.o" "-outputs={{.*}}libsycl-glibc-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-complex.o" "-outputs={{.*}}libsycl-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-complex-fp64.o" "-outputs={{.*}}libsycl-complex-fp64-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-cmath.o" "-outputs={{.*}}libsycl-cmath-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-cmath-fp64.o" "-outputs={{.*}}libsycl-cmath-fp64-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cassert.o" "-outputs={{.*}}libsycl-fallback-cassert-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-complex.o" "-outputs={{.*}}libsycl-fallback-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-complex-fp64.o" "-outputs={{.*}}libsycl-fallback-complex-fp64-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cmath.o" "-outputs={{.*}}libsycl-fallback-cmath-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_WITH_FP64-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cmath-fp64.o" "-outputs={{.*}}libsycl-fallback-cmath-fp64-{{.*}}.o" "-unbundle" + +/// ########################################################################### + +/// test behavior of -fno-sycl-device-lib=libc +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libc -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-complex.o" "-outputs={{.*}}libsycl-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-cmath.o" "-outputs={{.*}}libsycl-cmath-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-complex.o" "-outputs={{.*}}libsycl-fallback-complex-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBC-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cmath.o" "-outputs={{.*}}libsycl-fallback-cmath-{{.*}}.o" "-unbundle" + +/// ########################################################################### + +/// test behavior of -fno-sycl-device-lib=libm-fp32 +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBM_FP32 +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBM_FP32: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-glibc.o" "-outputs={{.*}}libsycl-glibc-{{.*}}.o" "-unbundle" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_LIBM_FP32-NEXT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice" "-inputs={{.*}}libsycl-fallback-cassert.o" "-outputs={{.*}}libsycl-fallback-cassert-{{.*}}.o" "-unbundle" + +/// ########################################################################### + +/// test behavior of disabling all device libraries +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libc,libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libc,all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libm-fp32,all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libm-fp64,all -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=libc,all,libm-fp64,libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB +// SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB: {{.*}}clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown-sycldevice" +// SYCL_DEVICE_LIB_UNBUNDLE_NO_DEVICE_LIB-NEXT: {{.*}}llvm-link{{.*}} {{.*}} "--suppress-warnings" + +/// ########################################################################### + +/// test invalid value for -f[no-]sycl-device-lib +// RUN: %clangxx -fsycl %s -fsycl-device-lib=libc,dummy -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_DEVICE_LIB_INVALID_VALUE +// RUN: %clangxx -fsycl %s -fno-sycl-device-lib=dummy,libm-fp32 -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=SYCL_NO_DEVICE_LIB_INVALID_VALUE +// SYCL_DEVICE_LIB_INVALID_VALUE: error: unsupported argument 'dummy' to option 'fsycl-device-lib=' +// SYCL_NO_DEVICE_LIB_INVALID_VALUE: error: unsupported argument 'dummy' to option 'fno-sycl-device-lib=' diff --git a/clang/test/Driver/sycl-device.cpp b/clang/test/Driver/sycl-device.cpp index d5e135323498b..15ca3f617c3ae 100644 --- a/clang/test/Driver/sycl-device.cpp +++ b/clang/test/Driver/sycl-device.cpp @@ -22,3 +22,9 @@ // RUN: %clang -### -fsycl %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-SYCL-STD_VERSION %s // CHECK-SYCL-STD_VERSION: clang{{.*}} "-sycl-std=2020" + +/// Check that -aux-triple is set correctly +// RUN: %clang -### -fsycl -target aarch64-linux-gnu %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-SYCL-AUX-TRIPLE %s +// TODO: %clang -### -fsycl -fsycl-device-only -target aarch64-linux-gnu +// CHECK-SYCL-AUX-TRIPLE: clang{{.*}} "-aux-triple" "aarch64-unknown-linux-gnu" diff --git a/clang/test/Driver/sycl-intelfpga-static-lib-win.cpp b/clang/test/Driver/sycl-intelfpga-static-lib-win.cpp new file mode 100644 index 0000000000000..1f55ecd8921ff --- /dev/null +++ b/clang/test/Driver/sycl-intelfpga-static-lib-win.cpp @@ -0,0 +1,33 @@ +/// +/// tests specific to -fintelfpga -fsycl w/ static libs +/// +// REQUIRES: clang-driver +// REQUIRES: system-windows + +// make dummy archive +// Build a fat static lib that will be used for all tests +// RUN: echo "void foo(void) {}" > %t1.cpp +// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fintelfpga %t1.cpp -c -o %t1_bundle.obj +// RUN: lib -out:%t.lib %t1_bundle.obj + +/// Check phases with static lib +// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all -fintelfpga %t.lib -ccc-print-phases 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK_PHASES %s +// CHECK_PHASES: 0: input, "[[INPUT:.+\.lib]]", object, (host-sycl) +// CHECK_PHASES: 1: linker, {0}, image, (host-sycl) +// CHECK_PHASES: 2: input, "[[INPUT]]", archive +// CHECK_PHASES: 3: clang-offload-unbundler, {2}, archive +// CHECK_PHASES: 4: linker, {3}, ir, (device-sycl) +// CHECK_PHASES: 5: sycl-post-link, {4}, ir, (device-sycl) +// CHECK_PHASES: 6: llvm-spirv, {5}, spirv, (device-sycl) +// CHECK_PHASES: 7: input, "[[INPUT]]", archive +// CHECK_PHASES: 8: clang-offload-unbundler, {7}, fpga_dependencies_list +// CHECK_PHASES: 9: backend-compiler, {6, 8}, fpga_aocx, (device-sycl) +// CHECK_PHASES: 10: clang-offload-wrapper, {9}, object, (device-sycl) +// CHECK_PHASES: 11: offload, "host-sycl (x86_64-pc-windows-msvc)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {10}, image + +/// Check for unbundle and use of deps in static lib +// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all -fintelfpga %t.lib -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK_UNBUNDLE %s +// CHECK_UNBUNDLE: clang-offload-bundler" "-type=aoo" "-targets=sycl-fpga_dep" "-inputs={{.*}}" "-outputs=[[DEPFILES:.+\.txt]]" "-unbundle" +// CHECK_UNBUNDLE: aoc{{.*}} "-dep-files=@[[DEPFILES]]" diff --git a/clang/test/Driver/sycl-intelfpga-static-lib.cpp b/clang/test/Driver/sycl-intelfpga-static-lib.cpp new file mode 100644 index 0000000000000..1a77afd98465a --- /dev/null +++ b/clang/test/Driver/sycl-intelfpga-static-lib.cpp @@ -0,0 +1,33 @@ +/// +/// tests specific to -fintelfpga -fsycl w/ static libs +/// +// REQUIRES: clang-driver + +// make dummy archive +// Build a fat static lib that will be used for all tests +// RUN: echo "void foo(void) {}" > %t1.cpp +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fintelfpga -fsycl %t1.cpp -c -o %t1_bundle.o +// RUN: llvm-ar cr %t.a %t1_bundle.o + +/// Check phases with static lib +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga %t.a -ccc-print-phases 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK_PHASES %s +// CHECK_PHASES: 0: input, "[[INPUT:.+\.a]]", object, (host-sycl) +// CHECK_PHASES: 1: linker, {0}, image, (host-sycl) +// CHECK_PHASES: 2: input, "[[INPUT]]", archive +// CHECK_PHASES: 3: partial-link, {2}, object +// CHECK_PHASES: 4: clang-offload-unbundler, {3}, object +// CHECK_PHASES: 5: linker, {4}, ir, (device-sycl) +// CHECK_PHASES: 6: sycl-post-link, {5}, ir, (device-sycl) +// CHECK_PHASES: 7: llvm-spirv, {6}, spirv, (device-sycl) +// CHECK_PHASES: 8: input, "[[INPUT]]", archive +// CHECK_PHASES: 9: clang-offload-unbundler, {8}, fpga_dependencies_list +// CHECK_PHASES: 10: backend-compiler, {7, 9}, fpga_aocx, (device-sycl) +// CHECK_PHASES: 11: clang-offload-wrapper, {10}, object, (device-sycl) +// CHECK_PHASES: 12: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {11}, image + +/// Check for unbundle and use of deps in static lib +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga %t.a -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK_UNBUNDLE %s +// CHECK_UNBUNDLE: clang-offload-bundler" "-type=aoo" "-targets=sycl-fpga_dep" "-inputs={{.*}}" "-outputs=[[DEPFILES:.+\.txt]]" "-unbundle" +// CHECK_UNBUNDLE: aoc{{.*}} "-dep-files=@[[DEPFILES]]" diff --git a/clang/test/Driver/sycl-offload-intelfpga.cpp b/clang/test/Driver/sycl-offload-intelfpga.cpp index 71d5c2bc76051..4f64388540916 100644 --- a/clang/test/Driver/sycl-offload-intelfpga.cpp +++ b/clang/test/Driver/sycl-offload-intelfpga.cpp @@ -21,11 +21,11 @@ /// -fintelfpga -fsycl-link tests // RUN: touch %t.o -// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -fsycl-link %t.o -o libfoo.a 2>&1 \ +// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -fsycl-link %t.o -o libfoo.a 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK,CHK-FPGA-EARLY %s -// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -fsycl-link=early %t.o -o libfoo.a 2>&1 \ +// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -fsycl-link=early %t.o -o libfoo.a 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK,CHK-FPGA-EARLY %s -// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -fsycl-link=image %t.o -o libfoo.a 2>&1 \ +// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -fsycl-link=image %t.o -o libfoo.a 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK,CHK-FPGA-IMAGE %s // CHK-FPGA-LINK-NOT: clang-offload-bundler{{.*}} "-check-section" // CHK-FPGA-LINK: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice" "-inputs=[[INPUT:.+\.o]]" "-outputs=[[OUTPUT1:.+\.o]]" "-unbundle" @@ -35,7 +35,12 @@ // CHK-FPGA-LINK: llvm-spirv{{.*}} "-o" "[[OUTPUT3:.+\.spv]]" "-spirv-max-version=1.1" "-spirv-debug-info-version=legacy" "-spirv-ext=+all,-SPV_INTEL_usm_storage_classes" "[[OUTPUT2]]" // CHK-FPGA-EARLY: aoc{{.*}} "-o" "[[OUTPUT4:.+\.aocr]]" "[[OUTPUT3]]" "-sycl" "-rtl" // CHK-FPGA-IMAGE: aoc{{.*}} "-o" "[[OUTPUT5:.+\.aocx]]" "[[OUTPUT3]]" "-sycl" -// CHK-FPGA-LINK: llvm-ar{{.*}} "cr" "libfoo.a" "[[INPUT]]" +// CHK-FPGA-LINK: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" "-host=x86_64-unknown-linux-gnu" {{.*}} "-kind=sycl" +// CHK-FPGA-LINK: llc{{.*}} "-o" "[[OBJOUTDEV:.+\.o]]" "[[WRAPOUT]]" +// CHK-FPGA-EARLY: clang-offload-wrapper{{.*}} "-host" "x86_64-unknown-linux-gnu" "-o" "[[WRAPOUTHOST:.+\.bc]]" "-kind=host" +// CHK-FPGA-EARLY: clang{{.*}} "-o" "[[OBJOUT:.+\.o]]" {{.*}} "[[WRAPOUTHOST]]" +// CHK-FPGA-EARLY: llvm-ar{{.*}} "cr" "libfoo.a" "[[OBJOUT]]" "[[OBJOUTDEV]]" +// CHK-FPGA-IMAGE: llvm-ar{{.*}} "cr" "libfoo.a" "[[INPUT]]" "[[OBJOUTDEV]]" // Output designation should not be used for unbundling step // RUN: touch %t.o @@ -50,9 +55,9 @@ /// -fintelfpga -fsycl-link clang-cl specific // RUN: touch %t.obj -// RUN: %clang_cl -### -fsycl -fintelfpga -fsycl-link %t.obj -Folibfoo.lib 2>&1 \ +// RUN: %clang_cl -### -fsycl -fintelfpga -fno-sycl-device-lib=all -fsycl-link %t.obj -Folibfoo.lib 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-WIN %s -// RUN: %clang_cl -### -fsycl -fintelfpga -fsycl-link %t.obj -o libfoo.lib 2>&1 \ +// RUN: %clang_cl -### -fsycl -fintelfpga -fno-sycl-device-lib=all -fsycl-link %t.obj -o libfoo.lib 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-WIN %s // CHK-FPGA-LINK-WIN: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice{{.*}}" "-inputs=[[INPUT:.+\.obj]]" "-outputs=[[OUTPUT1:.+\.obj]]" "-unbundle" // CHK-FPGA-LINK-WIN-NOT: clang-offload-bundler{{.*}} @@ -60,7 +65,11 @@ // CHK-FPGA-LINK-WIN: sycl-post-link{{.*}} "-ir-output-only" "-spec-const=default" "-o" "[[OUTPUT2:.+\.bc]]" "[[OUTPUT2_1]]" // CHK-FPGA-LINK-WIN: llvm-spirv{{.*}} "-o" "[[OUTPUT3:.+\.spv]]" "-spirv-max-version=1.1" "-spirv-debug-info-version=legacy" "-spirv-ext=+all,-SPV_INTEL_usm_storage_classes" "[[OUTPUT2]]" // CHK-FPGA-LINK-WIN: aoc{{.*}} "-o" "[[OUTPUT5:.+\.aocr]]" "[[OUTPUT3]]" "-sycl" "-rtl" -// CHK-FPGA-LINK-WIN: lib.exe{{.*}} "[[INPUT]]" {{.*}} "-OUT:libfoo.lib" +// CHK-FPGA-LINK-WIN: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-kind=sycl" +// CHK-FPGA-LINK-WIN: llc{{.*}} "-o" "[[OBJOUTDEV:.+\.obj]]" "[[WRAPOUT]]" +// CHK-FPGA-LINK-WIN: clang-offload-wrapper{{.*}} "-o" "[[WRAPOUTHOST:.+\.bc]]" "-kind=host" +// CHK-FPGA-LINK-WIN: clang{{.*}} "-o" "[[OBJOUT:.+\.obj]]" {{.*}} "[[WRAPOUTHOST]]" +// CHK-FPGA-LINK-WIN: lib.exe{{.*}} "[[OBJOUT]]" "[[OBJOUTDEV]]" {{.*}} "-OUT:libfoo.lib" /// Check -fintelfpga -fsycl-link with an FPGA archive // Create the dummy archive @@ -83,7 +92,7 @@ // CHK-FPGA-LINK-LIB-EARLY: clang-offload-wrapper{{.*}} "-host=x86_64-unknown-linux-gnu" "-target=fpga_aocr-intel-unknown-sycldevice" "-kind=sycl" "[[OUTPUT4]]" // CHK-FPGA-LINK-LIB: llc{{.*}} "-filetype=obj" "-o" "[[OUTPUT5:.+\.o]]" // CHK-FPGA-LINK-LIB: clang-offload-bundler{{.*}} "-type=aoo" "-targets=host-x86_64-unknown-linux-gnu" "-inputs=[[INPUT]]" "-outputs=[[OUTPUT1:.+\.txt]]" "-unbundle" -// CHK-FPGA-LINK-LIB: llvm-ar{{.*}} "cr" {{.*}} "@[[OUTPUT1]]" +// CHK-FPGA-LINK-LIB-IMAGE: llvm-ar{{.*}} "cr" {{.*}} "@[[OUTPUT1]]" /// Check the warning's emission for -fsycl-link's appending behavior // RUN: touch dummy.a @@ -185,29 +194,30 @@ /// -fintelfpga -fsycl-link from source // RUN: touch %t.cpp -// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-SRC,CHK-FPGA-LINK-SRC-DEFAULT %s -// RUN: %clang_cl -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-SRC,CHK-FPGA-LINK-SRC-CL %s +// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-SRC %s +// RUN: %clang_cl -### --target=x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-SRC %s // CHK-FPGA-LINK-SRC: 0: input, "[[INPUT:.+\.cpp]]", c++, (host-sycl) // CHK-FPGA-LINK-SRC: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) // CHK-FPGA-LINK-SRC: 2: input, "[[INPUT]]", c++, (device-sycl) // CHK-FPGA-LINK-SRC: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-FPGA-LINK-SRC: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-FPGA-LINK-SRC-DEFAULT: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, c++-cpp-output -// CHK-FPGA-LINK-SRC-CL: 5: offload, "host-sycl (x86_64-pc-windows-msvc)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, c++-cpp-output +// CHK-FPGA-LINK-SRC: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-FPGA-LINK-SRC: 6: compiler, {5}, ir, (host-sycl) // CHK-FPGA-LINK-SRC: 7: backend, {6}, assembler, (host-sycl) // CHK-FPGA-LINK-SRC: 8: assembler, {7}, object, (host-sycl) -// CHK-FPGA-LINK-SRC: 9: linker, {8}, archive, (host-sycl) -// CHK-FPGA-LINK-SRC: 10: compiler, {3}, ir, (device-sycl) -// CHK-FPGA-LINK-SRC: 11: linker, {10}, ir, (device-sycl) -// CHK-FPGA-LINK-SRC: 12: sycl-post-link, {11}, ir, (device-sycl) -// CHK-FPGA-LINK-SRC: 13: llvm-spirv, {12}, spirv, (device-sycl) -// CHK-FPGA-LINK-SRC: 14: backend-compiler, {13}, fpga_aocr, (device-sycl) -// CHK-FPGA-LINK-SRC: 15: clang-offload-wrapper, {14}, object, (device-sycl) -// CHK-FPGA-LINK-SRC-DEFAULT: 16: offload, "host-sycl (x86_64-unknown-linux-gnu)" {9}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {15}, archive -// CHK-FPGA-LINK-SRC-CL: 16: offload, "host-sycl (x86_64-pc-windows-msvc)" {9}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {15}, archive +// CHK-FPGA-LINK-SRC: 9: clang-offload-wrapper, {8}, ir, (host-sycl) +// CHK-FPGA-LINK-SRC: 10: backend, {9}, assembler, (host-sycl) +// CHK-FPGA-LINK-SRC: 11: assembler, {10}, object, (host-sycl) +// CHK-FPGA-LINK-SRC: 12: linker, {11}, archive, (host-sycl) +// CHK-FPGA-LINK-SRC: 13: compiler, {3}, ir, (device-sycl) +// CHK-FPGA-LINK-SRC: 14: linker, {13}, ir, (device-sycl) +// CHK-FPGA-LINK-SRC: 15: sycl-post-link, {14}, ir, (device-sycl) +// CHK-FPGA-LINK-SRC: 16: llvm-spirv, {15}, spirv, (device-sycl) +// CHK-FPGA-LINK-SRC: 17: backend-compiler, {16}, fpga_aocr, (device-sycl) +// CHK-FPGA-LINK-SRC: 18: clang-offload-wrapper, {17}, object, (device-sycl) +// CHK-FPGA-LINK-SRC: 19: offload, "host-sycl (x86_64-unknown-linux-gnu)" {12}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {18}, archive /// -fintelfpga with -reuse-exe= // RUN: touch %t.cpp @@ -275,9 +285,9 @@ /// -fintelfpga dependency file use from object phases test // RUN: touch %t-1.o -// RUN: %clangxx -fsycl -fintelfpga -ccc-print-phases -### %t-1.o 2>&1 \ +// RUN: %clangxx -fsycl -fno-sycl-device-lib=all -fintelfpga -ccc-print-phases -### %t-1.o 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES-OBJ-PHASES -DINPUT=%t-1.o %s -// RUN: %clang_cl -fsycl -fintelfpga -ccc-print-phases -### %t-1.o 2>&1 \ +// RUN: %clang_cl -fsycl -fno-sycl-device-lib=all -fintelfpga -ccc-print-phases -### %t-1.o 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES-OBJ-PHASES -DINPUT=%t-1.o %s // CHK-FPGA-DEP-FILES-OBJ-PHASES: 0: input, "[[INPUT]]", object, (host-sycl) // CHK-FPGA-DEP-FILES-OBJ-PHASES: 1: clang-offload-unbundler, {0}, object, (host-sycl) @@ -348,7 +358,7 @@ // RUN: llc -filetype=obj -o %t-aoco_cl.o %t-aoco_cl.bc // RUN: llvm-ar crv %t_aoco.a %t.o %t2.o %t-aoco.o // RUN: llvm-ar crv %t_aoco_cl.a %t.o %t2_cl.o %t-aoco_cl.o -// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -foffload-static-lib=%t_aoco.a %s -### -ccc-print-phases 2>&1 \ +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -foffload-static-lib=%t_aoco.a %s -### -ccc-print-phases 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-FPGA-AOCO-PHASES %s // CHK-FPGA-AOCO-PHASES: 0: input, "[[INPUTA:.+\.a]]", object, (host-sycl) // CHK-FPGA-AOCO-PHASES: 1: input, "[[INPUTCPP:.+\.cpp]]", c++, (host-sycl) @@ -368,14 +378,16 @@ // CHK-FPGA-AOCO-PHASES: 15: linker, {11, 14}, ir, (device-sycl) // CHK-FPGA-AOCO-PHASES: 16: sycl-post-link, {15}, ir, (device-sycl) // CHK-FPGA-AOCO-PHASES: 17: llvm-spirv, {16}, spirv, (device-sycl) -// CHK-FPGA-AOCO-PHASES: 18: input, "[[INPUTA]]", fpga_aoco -// CHK-FPGA-AOCO-PHASES: 19: clang-offload-unbundler, {18}, fpga_aoco -// CHK-FPGA-AOCO-PHASES: 20: backend-compiler, {17, 19}, fpga_aocx, (device-sycl) -// CHK-FPGA-AOCO-PHASES: 21: clang-offload-wrapper, {20}, object, (device-sycl) -// CHK-FPGA-AOCO-PHASES: 22: offload, "host-sycl (x86_64-unknown-linux-gnu)" {10}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {21}, image +// CHK-FPGA-AOCO-PHASES: 18: input, "[[INPUTA]]", archive +// CHK-FPGA-AOCO-PHASES: 19: clang-offload-unbundler, {18}, fpga_dependencies_list +// CHK-FPGA-AOCO-PHASES: 20: input, "[[INPUTA]]", fpga_aoco +// CHK-FPGA-AOCO-PHASES: 21: clang-offload-unbundler, {20}, fpga_aoco +// CHK-FPGA-AOCO-PHASES: 22: backend-compiler, {17, 19, 21}, fpga_aocx, (device-sycl) +// CHK-FPGA-AOCO-PHASES: 23: clang-offload-wrapper, {22}, object, (device-sycl) +// CHK-FPGA-AOCO-PHASES: 24: offload, "host-sycl (x86_64-unknown-linux-gnu)" {10}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {23}, image /// FPGA AOCO Windows phases check -// RUN: %clang_cl -fsycl -fintelfpga -foffload-static-lib=%t_aoco_cl.a %s -### -ccc-print-phases 2>&1 \ +// RUN: %clang_cl -fsycl -fno-sycl-device-lib=all -fintelfpga -foffload-static-lib=%t_aoco_cl.a %s -### -ccc-print-phases 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCO-PHASES-WIN %s // CHK-FPGA-AOCO-PHASES-WIN: 0: input, "{{.*}}", object, (host-sycl) // CHK-FPGA-AOCO-PHASES-WIN: 1: input, "[[INPUTSRC:.+\.cpp]]", c++, (host-sycl) @@ -394,20 +406,22 @@ // CHK-FPGA-AOCO-PHASES-WIN: 14: linker, {11, 13}, ir, (device-sycl) // CHK-FPGA-AOCO-PHASES-WIN: 15: sycl-post-link, {14}, ir, (device-sycl) // CHK-FPGA-AOCO-PHASES-WIN: 16: llvm-spirv, {15}, spirv, (device-sycl) -// CHK-FPGA-AOCO-PHASES-WIN: 17: input, "[[INPUTA]]", fpga_aoco -// CHK-FPGA-AOCO-PHASES-WIN: 18: clang-offload-unbundler, {17}, fpga_aoco -// CHK-FPGA-AOCO-PHASES-WIN: 19: backend-compiler, {16, 18}, fpga_aocx, (device-sycl) -// CHK-FPGA-AOCO-PHASES-WIN: 20: clang-offload-wrapper, {19}, object, (device-sycl) -// CHK-FPGA-AOCO-PHASES-WIN: 21: offload, "host-sycl (x86_64-pc-windows-msvc)" {10}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {20}, image +// CHK-FPGA-AOCO-PHASES-WIN: 17: input, "[[INPUTA]]", archive +// CHK-FPGA-AOCO-PHASES-WIN: 18: clang-offload-unbundler, {17}, fpga_dependencies_list +// CHK-FPGA-AOCO-PHASES-WIN: 19: input, "[[INPUTA]]", fpga_aoco +// CHK-FPGA-AOCO-PHASES-WIN: 20: clang-offload-unbundler, {19}, fpga_aoco +// CHK-FPGA-AOCO-PHASES-WIN: 21: backend-compiler, {16, 18, 20}, fpga_aocx, (device-sycl) +// CHK-FPGA-AOCO-PHASES-WIN: 22: clang-offload-wrapper, {21}, object, (device-sycl) +// CHK-FPGA-AOCO-PHASES-WIN: 23: offload, "host-sycl (x86_64-pc-windows-msvc)" {10}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {22}, image /// aoco test, checking tools -// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -foffload-static-lib=%t_aoco.a -### %s 2>&1 \ +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -foffload-static-lib=%t_aoco.a -### %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCO,CHK-FPGA-AOCO-LIN %s -// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t_aoco.a -### %s 2>&1 \ +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga %t_aoco.a -### %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCO,CHK-FPGA-AOCO-LIN %s -// RUN: %clang_cl -fsycl -fintelfpga -foffload-static-lib=%t_aoco_cl.a -### %s 2>&1 \ +// RUN: %clang_cl -fsycl -fno-sycl-device-lib=all -fintelfpga -foffload-static-lib=%t_aoco_cl.a -### %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCO,CHK-FPGA-AOCO-WIN %s -// RUN: %clang_cl -fsycl -fintelfpga %t_aoco_cl.a -### %s 2>&1 \ +// RUN: %clang_cl -fsycl -fno-sycl-device-lib=all -fintelfpga %t_aoco_cl.a -### %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCO,CHK-FPGA-AOCO-WIN %s // CHK-FPGA-AOCO-LIN: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aoco-intel-unknown-sycldevice" "-inputs=[[INPUTLIB:.+\.a]]" "-check-section" // CHK-FPGA-AOCO-LIN: clang{{.*}} "-emit-obj" {{.*}} "-o" "[[HOSTOBJ:.+\.o]]" diff --git a/clang/test/Driver/sycl-offload-static-lib-2.cpp b/clang/test/Driver/sycl-offload-static-lib-2.cpp index eff45a9d19f30..cc97a6a53a8de 100644 --- a/clang/test/Driver/sycl-offload-static-lib-2.cpp +++ b/clang/test/Driver/sycl-offload-static-lib-2.cpp @@ -99,9 +99,9 @@ /// ########################################################################### /// test behaviors of static lib with no source/object -// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -L/dummy/dir %t.a -### 2>&1 \ +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -L/dummy/dir %t.a -### 2>&1 \ // RUN: | FileCheck %s -check-prefix=STATIC_LIB_NOSRC -DINPUTLIB=%t.a -// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -L/dummy/dir %t.lo -### 2>&1 \ +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -L/dummy/dir %t.lo -### 2>&1 \ // RUN: | FileCheck %s -check-prefix=STATIC_LIB_NOSRC -DINPUTLIB=%t.lo // STATIC_LIB_NOSRC: clang-offload-bundler{{.*}} "-type=ao" "-targets=host-x86_64-unknown-linux-gnu" "-inputs=[[INPUTLIB]]" "-check-section" // STATIC_LIB_NOSRC: ld{{.*}} "-r" "-o" "[[PARTIALOBJ:.+\.o]]" "{{.*}}crt1.o" {{.*}} "-L/dummy/dir" {{.*}} "[[INPUTLIB]]" diff --git a/clang/test/Driver/sycl-offload-static-lib.cpp b/clang/test/Driver/sycl-offload-static-lib.cpp index e32b244162e38..95cb56245d539 100644 --- a/clang/test/Driver/sycl-offload-static-lib.cpp +++ b/clang/test/Driver/sycl-offload-static-lib.cpp @@ -47,7 +47,7 @@ /// test behaviors of -foffload-static-lib= from source // RUN: touch %t.a -// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -foffload-static-lib=%t.a -ccc-print-phases %s 2>&1 \ +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -foffload-static-lib=%t.a -ccc-print-phases %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB_SRC // FOFFLOAD_STATIC_LIB_SRC: 0: input, "[[INPUTA:.+\.a]]", object, (host-sycl) @@ -122,9 +122,9 @@ /// ########################################################################### /// test behaviors of -foffload-static-lib with no source/object -// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -L/dummy/dir -foffload-static-lib=%t.a -### -ccc-print-phases 2>&1 \ +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -L/dummy/dir -foffload-static-lib=%t.a -### -ccc-print-phases 2>&1 \ // RUN: | FileCheck %s -check-prefixes=FOFFLOAD_STATIC_LIB_NOSRC_PHASES,FOFFLOAD_STATIC_LIB_NOSRC_PHASES_1 -// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -L/dummy/dir -foffload-whole-static-lib=%t.a -### -ccc-print-phases 2>&1 \ +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -L/dummy/dir -foffload-whole-static-lib=%t.a -### -ccc-print-phases 2>&1 \ // RUN: | FileCheck %s -check-prefixes=FOFFLOAD_STATIC_LIB_NOSRC_PHASES,FOFFLOAD_STATIC_LIB_NOSRC_PHASES_2 // FOFFLOAD_STATIC_LIB_NOSRC_PHASES: 0: input, "[[INPUTA:.+\.a]]", object, (host-sycl) // FOFFLOAD_STATIC_LIB_NOSRC_PHASES: 1: linker, {0}, image, (host-sycl) diff --git a/clang/test/Driver/sycl-offload-win.c b/clang/test/Driver/sycl-offload-win.c index 87db2f5fdc15a..9071d99f1a7bd 100644 --- a/clang/test/Driver/sycl-offload-win.c +++ b/clang/test/Driver/sycl-offload-win.c @@ -57,18 +57,18 @@ /// Test behaviors of -foffload-static-lib= from source. // RUN: touch %t.lib -// RUN: %clang --target=x86_64-pc-windows-msvc -fsycl -foffload-static-lib=%t.lib -ccc-print-phases %s 2>&1 \ +// RUN: %clang --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all -foffload-static-lib=%t.lib -ccc-print-phases %s 2>&1 \ // RUN: | FileCheck -DLIB=%t.lib %s -check-prefix=FOFFLOAD_STATIC_LIB_SRC -// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -foffload-static-lib=%t.lib -ccc-print-phases %s 2>&1 \ +// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all -foffload-static-lib=%t.lib -ccc-print-phases %s 2>&1 \ // RUN: | FileCheck -DLIB=%t.lib %s -check-prefix=FOFFLOAD_STATIC_LIB_SRC // FOFFLOAD_STATIC_LIB_SRC: 0: input, "[[INPUTLIB:.+\.lib]]", object, (host-sycl) -// FOFFLOAD_STATIC_LIB_SRC: 1: input, "[[INPUTC:.+\.c]]", c, (host-sycl) -// FOFFLOAD_STATIC_LIB_SRC: 2: preprocessor, {1}, cpp-output, (host-sycl) -// FOFFLOAD_STATIC_LIB_SRC: 3: input, "[[INPUTC]]", c, (device-sycl) -// FOFFLOAD_STATIC_LIB_SRC: 4: preprocessor, {3}, cpp-output, (device-sycl) +// FOFFLOAD_STATIC_LIB_SRC: 1: input, "[[INPUTC:.+\.c]]", c++, (host-sycl) +// FOFFLOAD_STATIC_LIB_SRC: 2: preprocessor, {1}, c++-cpp-output, (host-sycl) +// FOFFLOAD_STATIC_LIB_SRC: 3: input, "[[INPUTC]]", c++, (device-sycl) +// FOFFLOAD_STATIC_LIB_SRC: 4: preprocessor, {3}, c++-cpp-output, (device-sycl) // FOFFLOAD_STATIC_LIB_SRC: 5: compiler, {4}, sycl-header, (device-sycl) -// FOFFLOAD_STATIC_LIB_SRC: 6: offload, "host-sycl (x86_64-pc-windows-msvc)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, cpp-output +// FOFFLOAD_STATIC_LIB_SRC: 6: offload, "host-sycl (x86_64-pc-windows-msvc)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, c++-cpp-output // FOFFLOAD_STATIC_LIB_SRC: 7: compiler, {6}, ir, (host-sycl) // FOFFLOAD_STATIC_LIB_SRC: 8: backend, {7}, assembler, (host-sycl) // FOFFLOAD_STATIC_LIB_SRC: 9: assembler, {8}, object, (host-sycl) @@ -97,9 +97,9 @@ // Check for /P behaviors // RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -P %s -### 2>&1 | FileCheck -check-prefix=FSYCL_P %s -// FSYCL_P: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown-sycldevice" {{.*}} "-E" {{.*}} "-o" "[[DEVICEPP:.+\.i]]" -// FSYCL_P: clang{{.*}} "-cc1" "-triple" "x86_64-pc-windows-msvc{{.*}}" {{.*}} "-E" {{.*}} "-o" "[[HOSTPP:.+\.i]]" -// FSYCL_P: clang-offload-bundler{{.*}} "-type=i" "-targets=sycl-spir64-unknown-unknown-sycldevice,host-x86_64-pc-windows-msvc" {{.*}} "-inputs=[[DEVICEPP]],[[HOSTPP]]" +// FSYCL_P: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown-sycldevice" {{.*}} "-E" {{.*}} "-o" "[[DEVICEPP:.+\.ii]]" +// FSYCL_P: clang{{.*}} "-cc1" "-triple" "x86_64-pc-windows-msvc{{.*}}" {{.*}} "-E" {{.*}} "-o" "[[HOSTPP:.+\.ii]]" +// FSYCL_P: clang-offload-bundler{{.*}} "-type=ii" "-targets=sycl-spir64-unknown-unknown-sycldevice,host-x86_64-pc-windows-msvc" {{.*}} "-inputs=[[DEVICEPP]],[[HOSTPP]]" // TODO: SYCL specific fail - analyze and enable // XFAIL: windows-msvc diff --git a/clang/test/Driver/sycl-offload-with-split.c b/clang/test/Driver/sycl-offload-with-split.c index 4d01f4d5fb800..626af33fb7b73 100644 --- a/clang/test/Driver/sycl-offload-with-split.c +++ b/clang/test/Driver/sycl-offload-with-split.c @@ -12,25 +12,25 @@ /// preprocessor and another one joining the device linking outputs to the host /// action. The same graph should be generated when no -fsycl-targets is used /// The same phase graph will be used with -fsycl-use-bitcode -// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-DEFAULT-MODE %s -// RUN: %clang_cl -ccc-print-phases -fsycl -fsycl-device-code-split=per_source -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang_cl -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split=per_source -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-CL-MODE %s -// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split=per_source -fno-sycl-use-bitcode %s 2>&1 \ +// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split=per_source -fno-sycl-use-bitcode %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-DEFAULT-MODE %s -// RUN: %clang_cl -ccc-print-phases -fsycl -fsycl-device-code-split=per_source -fno-sycl-use-bitcode %s 2>&1 \ +// RUN: %clang_cl -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split=per_source -fno-sycl-use-bitcode %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-CL-MODE %s -// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split=per_source -fsycl-use-bitcode %s 2>&1 \ +// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split=per_source -fsycl-use-bitcode %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-DEFAULT-MODE %s -// RUN: %clang_cl -ccc-print-phases -fsycl -fsycl-device-code-split=per_source -fsycl-use-bitcode %s 2>&1 \ +// RUN: %clang_cl -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split=per_source -fsycl-use-bitcode %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-CL-MODE %s -// CHK-PHASES: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-PHASES: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-PHASES: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASES: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-PHASES: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-PHASES: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-PHASES: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASES: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-PHASES: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-PHASES-DEFAULT-MODE: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output -// CHK-PHASES-CL-MODE: 5: offload, "host-sycl (x86_64-pc-windows-msvc)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-PHASES-DEFAULT-MODE: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output +// CHK-PHASES-CL-MODE: 5: offload, "host-sycl (x86_64-pc-windows-msvc)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-PHASES: 6: compiler, {5}, ir, (host-sycl) // CHK-PHASES: 7: backend, {6}, assembler, (host-sycl) // CHK-PHASES: 8: assembler, {7}, object, (host-sycl) @@ -49,15 +49,15 @@ /// Check the phases also add a library to make sure it is treated as input by /// the device. -// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -lsomelib -fsycl -fsycl-device-code-split -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -lsomelib -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-PHASES-LIB %s // CHK-PHASES-LIB: 0: input, "somelib", object, (host-sycl) -// CHK-PHASES-LIB: 1: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-PHASES-LIB: 2: preprocessor, {1}, cpp-output, (host-sycl) -// CHK-PHASES-LIB: 3: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASES-LIB: 4: preprocessor, {3}, cpp-output, (device-sycl) +// CHK-PHASES-LIB: 1: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-PHASES-LIB: 2: preprocessor, {1}, c++-cpp-output, (host-sycl) +// CHK-PHASES-LIB: 3: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASES-LIB: 4: preprocessor, {3}, c++-cpp-output, (device-sycl) // CHK-PHASES-LIB: 5: compiler, {4}, sycl-header, (device-sycl) -// CHK-PHASES-LIB: 6: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, cpp-output +// CHK-PHASES-LIB: 6: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, c++-cpp-output // CHK-PHASES-LIB: 7: compiler, {6}, ir, (host-sycl) // CHK-PHASES-LIB: 8: backend, {7}, assembler, (host-sycl) // CHK-PHASES-LIB: 9: assembler, {8}, object, (host-sycl) @@ -75,25 +75,25 @@ /// Check the phases when using and multiple source files // RUN: echo " " > %t.c -// RUN: %clang -ccc-print-phases -lsomelib -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -fsycl-targets=spir64-unknown-unknown-sycldevice %s %t.c 2>&1 \ +// RUN: %clang -ccc-print-phases -lsomelib -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64-unknown-unknown-sycldevice %s %t.c 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-PHASES-FILES %s // CHK-PHASES-FILES: 0: input, "somelib", object, (host-sycl) -// CHK-PHASES-FILES: 1: input, "[[INPUT1:.+\.c]]", c, (host-sycl) -// CHK-PHASES-FILES: 2: preprocessor, {1}, cpp-output, (host-sycl) -// CHK-PHASES-FILES: 3: input, "[[INPUT1]]", c, (device-sycl) -// CHK-PHASES-FILES: 4: preprocessor, {3}, cpp-output, (device-sycl) +// CHK-PHASES-FILES: 1: input, "[[INPUT1:.+\.c]]", c++, (host-sycl) +// CHK-PHASES-FILES: 2: preprocessor, {1}, c++-cpp-output, (host-sycl) +// CHK-PHASES-FILES: 3: input, "[[INPUT1]]", c++, (device-sycl) +// CHK-PHASES-FILES: 4: preprocessor, {3}, c++-cpp-output, (device-sycl) // CHK-PHASES-FILES: 5: compiler, {4}, sycl-header, (device-sycl) -// CHK-PHASES-FILES: 6: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, cpp-output +// CHK-PHASES-FILES: 6: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, c++-cpp-output // CHK-PHASES-FILES: 7: compiler, {6}, ir, (host-sycl) // CHK-PHASES-FILES: 8: backend, {7}, assembler, (host-sycl) // CHK-PHASES-FILES: 9: assembler, {8}, object, (host-sycl) -// CHK-PHASES-FILES: 10: input, "[[INPUT2:.+\.c]]", c, (host-sycl) -// CHK-PHASES-FILES: 11: preprocessor, {10}, cpp-output, (host-sycl) -// CHK-PHASES-FILES: 12: input, "[[INPUT2]]", c, (device-sycl) -// CHK-PHASES-FILES: 13: preprocessor, {12}, cpp-output, (device-sycl) +// CHK-PHASES-FILES: 10: input, "[[INPUT2:.+\.c]]", c++, (host-sycl) +// CHK-PHASES-FILES: 11: preprocessor, {10}, c++-cpp-output, (host-sycl) +// CHK-PHASES-FILES: 12: input, "[[INPUT2]]", c++, (device-sycl) +// CHK-PHASES-FILES: 13: preprocessor, {12}, c++-cpp-output, (device-sycl) // CHK-PHASES-FILES: 14: compiler, {13}, sycl-header, (device-sycl) -// CHK-PHASES-FILES: 15: offload, "host-sycl (x86_64-unknown-linux-gnu)" {11}, "device-sycl (spir64-unknown-unknown-sycldevice)" {14}, cpp-output +// CHK-PHASES-FILES: 15: offload, "host-sycl (x86_64-unknown-linux-gnu)" {11}, "device-sycl (spir64-unknown-unknown-sycldevice)" {14}, c++-cpp-output // CHK-PHASES-FILES: 16: compiler, {15}, ir, (host-sycl) // CHK-PHASES-FILES: 17: backend, {16}, assembler, (host-sycl) // CHK-PHASES-FILES: 18: assembler, {17}, object, (host-sycl) @@ -112,11 +112,11 @@ /// Check separate compilation with offloading - unbundling actions // RUN: touch %t.o -// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -o %t.out -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %t.o 2>&1 \ +// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -o %t.out -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %t.o 2>&1 \ // RUN: | FileCheck -DINPUT=%t.o -check-prefix=CHK-UBACTIONS %s // RUN: mkdir -p %t_dir // RUN: touch %t_dir/dummy -// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -o %t.out -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %t_dir/dummy 2>&1 \ +// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -o %t.out -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %t_dir/dummy 2>&1 \ // RUN: | FileCheck -DINPUT=%t_dir/dummy -check-prefix=CHK-UBACTIONS %s // CHK-UBACTIONS: 0: input, "somelib", object, (host-sycl) // CHK-UBACTIONS: 1: input, "[[INPUT]]", object, (host-sycl) @@ -134,17 +134,17 @@ /// Check separate compilation with offloading - unbundling with source // RUN: touch %t.o -// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -lsomelib -fsycl -fsycl-device-code-split %t.o -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -lsomelib -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split %t.o -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-UBUACTIONS %s // CHK-UBUACTIONS: 0: input, "somelib", object, (host-sycl) // CHK-UBUACTIONS: 1: input, "[[INPUT1:.+\.o]]", object, (host-sycl) // CHK-UBUACTIONS: 2: clang-offload-unbundler, {1}, object, (host-sycl) -// CHK-UBUACTIONS: 3: input, "[[INPUT2:.+\.c]]", c, (host-sycl) -// CHK-UBUACTIONS: 4: preprocessor, {3}, cpp-output, (host-sycl) -// CHK-UBUACTIONS: 5: input, "[[INPUT2]]", c, (device-sycl) -// CHK-UBUACTIONS: 6: preprocessor, {5}, cpp-output, (device-sycl) +// CHK-UBUACTIONS: 3: input, "[[INPUT2:.+\.c]]", c++, (host-sycl) +// CHK-UBUACTIONS: 4: preprocessor, {3}, c++-cpp-output, (host-sycl) +// CHK-UBUACTIONS: 5: input, "[[INPUT2]]", c++, (device-sycl) +// CHK-UBUACTIONS: 6: preprocessor, {5}, c++-cpp-output, (device-sycl) // CHK-UBUACTIONS: 7: compiler, {6}, sycl-header, (device-sycl) -// CHK-UBUACTIONS: 8: offload, "host-sycl (x86_64-unknown-linux-gnu)" {4}, "device-sycl (spir64-unknown-unknown-sycldevice)" {7}, cpp-output +// CHK-UBUACTIONS: 8: offload, "host-sycl (x86_64-unknown-linux-gnu)" {4}, "device-sycl (spir64-unknown-unknown-sycldevice)" {7}, c++-cpp-output // CHK-UBUACTIONS: 9: compiler, {8}, ir, (host-sycl) // CHK-UBUACTIONS: 10: backend, {9}, assembler, (host-sycl) // CHK-UBUACTIONS: 11: assembler, {10}, object, (host-sycl) @@ -161,20 +161,20 @@ /// ########################################################################### /// Ahead of Time compilation for fpga, gen, cpu -// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fsycl-device-code-split -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-PHASES-AOT,CHK-PHASES-FPGA -// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fsycl-device-code-split -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-PHASES-AOT,CHK-PHASES-GEN -// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fsycl-device-code-split -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-PHASES-AOT,CHK-PHASES-CPU -// CHK-PHASES-AOT: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-PHASES-AOT: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-PHASES-AOT: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASES-AOT: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-PHASES-AOT: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-PHASES-AOT: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-PHASES-AOT: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASES-AOT: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-PHASES-AOT: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-PHASES-FPGA: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, cpp-output -// CHK-PHASES-GEN: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_gen-unknown-unknown-sycldevice)" {4}, cpp-output -// CHK-PHASES-CPU: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_x86_64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-PHASES-FPGA: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, c++-cpp-output +// CHK-PHASES-GEN: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_gen-unknown-unknown-sycldevice)" {4}, c++-cpp-output +// CHK-PHASES-CPU: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_x86_64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-PHASES-AOT: 6: compiler, {5}, ir, (host-sycl) // CHK-PHASES-AOT: 7: backend, {6}, assembler, (host-sycl) // CHK-PHASES-AOT: 8: assembler, {7}, object, (host-sycl) @@ -196,13 +196,13 @@ /// ########################################################################### /// Ahead of Time compilation for fpga, gen, cpu - tool invocation -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -fintelfpga %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fintelfpga %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-GEN -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-CPU // CHK-TOOLS-AOT: clang{{.*}} "-fsycl-is-device" {{.*}} "-o" "[[OUTPUT1:.+\.bc]]" // CHK-TOOLS-AOT: llvm-link{{.*}} "[[OUTPUT1]]" "-o" "[[OUTPUT2:.+\.bc]]" @@ -226,22 +226,22 @@ /// ########################################################################### /// offload with multiple targets, including AOT -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-device-code-split -fsycl-targets=spir64-unknown-unknown-sycldevice,spir64_fpga-unknown-unknown-sycldevice,spir64_gen-unknown-unknown-sycldevice -### -ccc-print-phases %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-device-code-split -fsycl-targets=spir64-unknown-unknown-sycldevice,spir64_fpga-unknown-unknown-sycldevice,spir64_gen-unknown-unknown-sycldevice -### -ccc-print-phases %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-PHASE-MULTI-TARG %s -// CHK-PHASE-MULTI-TARG: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-PHASE-MULTI-TARG: 1: preprocessor, {0}, cpp-output, (host-sycl) +// CHK-PHASE-MULTI-TARG: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-PHASE-MULTI-TARG: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) -// CHK-PHASE-MULTI-TARG: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASE-MULTI-TARG: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-PHASE-MULTI-TARG: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASE-MULTI-TARG: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-PHASE-MULTI-TARG: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-PHASE-MULTI-TARG: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-PHASE-MULTI-TARG: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-PHASE-MULTI-TARG: 6: compiler, {5}, ir, (host-sycl) // CHK-PHASE-MULTI-TARG: 7: backend, {6}, assembler, (host-sycl) // CHK-PHASE-MULTI-TARG: 8: assembler, {7}, object, (host-sycl) // CHK-PHASE-MULTI-TARG: 9: linker, {8}, image, (host-sycl) -// CHK-PHASE-MULTI-TARG: 10: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASE-MULTI-TARG: 11: preprocessor, {10}, cpp-output, (device-sycl) +// CHK-PHASE-MULTI-TARG: 10: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASE-MULTI-TARG: 11: preprocessor, {10}, c++-cpp-output, (device-sycl) // CHK-PHASE-MULTI-TARG: 12: compiler, {11}, ir, (device-sycl) // CHK-PHASE-MULTI-TARG: 13: linker, {12}, ir, (device-sycl) // CHK-PHASE-MULTI-TARG: 14: sycl-post-link, {13}, tempfiletable, (device-sycl) @@ -250,8 +250,8 @@ // CHK-PHASE-MULTI-TARG: 17: file-table-tform, {14, 16}, tempfiletable, (device-sycl) // CHK-PHASE-MULTI-TARG: 18: clang-offload-wrapper, {17}, object, (device-sycl) -// CHK-PHASE-MULTI-TARG: 19: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASE-MULTI-TARG: 20: preprocessor, {19}, cpp-output, (device-sycl) +// CHK-PHASE-MULTI-TARG: 19: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASE-MULTI-TARG: 20: preprocessor, {19}, c++-cpp-output, (device-sycl) // CHK-PHASE-MULTI-TARG: 21: compiler, {20}, ir, (device-sycl) // CHK-PHASE-MULTI-TARG: 22: linker, {21}, ir, (device-sycl) // CHK-PHASE-MULTI-TARG: 23: sycl-post-link, {22}, tempfiletable, (device-sycl) diff --git a/clang/test/Driver/sycl-offload.c b/clang/test/Driver/sycl-offload.c index aeea104e524bd..6caa5a5a3f362 100644 --- a/clang/test/Driver/sycl-offload.c +++ b/clang/test/Driver/sycl-offload.c @@ -161,25 +161,25 @@ /// preprocessor and another one joining the device linking outputs to the host /// action. The same graph should be generated when no -fsycl-targets is used /// The same phase graph will be used with -fsycl-use-bitcode -// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice -fno-sycl-device-lib=all %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-DEFAULT-MODE %s -// RUN: %clang_cl -ccc-print-phases -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang_cl -ccc-print-phases -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice -fno-sycl-device-lib=all %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-CL-MODE %s -// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-use-bitcode %s 2>&1 \ +// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-use-bitcode -fno-sycl-device-lib=all %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-DEFAULT-MODE %s -// RUN: %clang_cl -ccc-print-phases -fsycl -fno-sycl-use-bitcode %s 2>&1 \ +// RUN: %clang_cl -ccc-print-phases -fsycl -fno-sycl-use-bitcode -fno-sycl-device-lib=all %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-CL-MODE %s -// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-use-bitcode %s 2>&1 \ +// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fsycl-use-bitcode -fno-sycl-device-lib=all %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-DEFAULT-MODE %s -// RUN: %clang_cl -ccc-print-phases -fsycl -fsycl-use-bitcode %s 2>&1 \ +// RUN: %clang_cl -ccc-print-phases -fsycl -fsycl-use-bitcode -fno-sycl-device-lib=all %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-PHASES,CHK-PHASES-CL-MODE %s -// CHK-PHASES: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-PHASES: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-PHASES: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASES: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-PHASES: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-PHASES: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-PHASES: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASES: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-PHASES: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-PHASES-DEFAULT-MODE: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output -// CHK-PHASES-CL-MODE: 5: offload, "host-sycl (x86_64-pc-windows-msvc)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-PHASES-DEFAULT-MODE: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output +// CHK-PHASES-CL-MODE: 5: offload, "host-sycl (x86_64-pc-windows-msvc)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-PHASES: 6: compiler, {5}, ir, (host-sycl) // CHK-PHASES: 7: backend, {6}, assembler, (host-sycl) // CHK-PHASES: 8: assembler, {7}, object, (host-sycl) @@ -208,15 +208,15 @@ /// Check the phases also add a library to make sure it is treated as input by /// the device. -// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -lsomelib -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -ccc-print-phases -target x86_64-unknown-linux-gnu -lsomelib -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice -fno-sycl-device-lib=all %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-PHASES-LIB %s // CHK-PHASES-LIB: 0: input, "somelib", object, (host-sycl) -// CHK-PHASES-LIB: 1: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-PHASES-LIB: 2: preprocessor, {1}, cpp-output, (host-sycl) -// CHK-PHASES-LIB: 3: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASES-LIB: 4: preprocessor, {3}, cpp-output, (device-sycl) +// CHK-PHASES-LIB: 1: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-PHASES-LIB: 2: preprocessor, {1}, c++-cpp-output, (host-sycl) +// CHK-PHASES-LIB: 3: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASES-LIB: 4: preprocessor, {3}, c++-cpp-output, (device-sycl) // CHK-PHASES-LIB: 5: compiler, {4}, sycl-header, (device-sycl) -// CHK-PHASES-LIB: 6: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, cpp-output +// CHK-PHASES-LIB: 6: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, c++-cpp-output // CHK-PHASES-LIB: 7: compiler, {6}, ir, (host-sycl) // CHK-PHASES-LIB: 8: backend, {7}, assembler, (host-sycl) // CHK-PHASES-LIB: 9: assembler, {8}, object, (host-sycl) @@ -241,25 +241,25 @@ /// Check the phases when using and multiple source files // RUN: echo " " > %t.c -// RUN: %clang -ccc-print-phases -lsomelib -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice %s %t.c 2>&1 \ +// RUN: %clang -ccc-print-phases -lsomelib -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice -fno-sycl-device-lib=all %s %t.c 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-PHASES-FILES %s // CHK-PHASES-FILES: 0: input, "somelib", object, (host-sycl) -// CHK-PHASES-FILES: 1: input, "[[INPUT1:.+\.c]]", c, (host-sycl) -// CHK-PHASES-FILES: 2: preprocessor, {1}, cpp-output, (host-sycl) -// CHK-PHASES-FILES: 3: input, "[[INPUT1]]", c, (device-sycl) -// CHK-PHASES-FILES: 4: preprocessor, {3}, cpp-output, (device-sycl) +// CHK-PHASES-FILES: 1: input, "[[INPUT1:.+\.c]]", c++, (host-sycl) +// CHK-PHASES-FILES: 2: preprocessor, {1}, c++-cpp-output, (host-sycl) +// CHK-PHASES-FILES: 3: input, "[[INPUT1]]", c++, (device-sycl) +// CHK-PHASES-FILES: 4: preprocessor, {3}, c++-cpp-output, (device-sycl) // CHK-PHASES-FILES: 5: compiler, {4}, sycl-header, (device-sycl) -// CHK-PHASES-FILES: 6: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, cpp-output +// CHK-PHASES-FILES: 6: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, c++-cpp-output // CHK-PHASES-FILES: 7: compiler, {6}, ir, (host-sycl) // CHK-PHASES-FILES: 8: backend, {7}, assembler, (host-sycl) // CHK-PHASES-FILES: 9: assembler, {8}, object, (host-sycl) -// CHK-PHASES-FILES: 10: input, "[[INPUT2:.+\.c]]", c, (host-sycl) -// CHK-PHASES-FILES: 11: preprocessor, {10}, cpp-output, (host-sycl) -// CHK-PHASES-FILES: 12: input, "[[INPUT2]]", c, (device-sycl) -// CHK-PHASES-FILES: 13: preprocessor, {12}, cpp-output, (device-sycl) +// CHK-PHASES-FILES: 10: input, "[[INPUT2:.+\.c]]", c++, (host-sycl) +// CHK-PHASES-FILES: 11: preprocessor, {10}, c++-cpp-output, (host-sycl) +// CHK-PHASES-FILES: 12: input, "[[INPUT2]]", c++, (device-sycl) +// CHK-PHASES-FILES: 13: preprocessor, {12}, c++-cpp-output, (device-sycl) // CHK-PHASES-FILES: 14: compiler, {13}, sycl-header, (device-sycl) -// CHK-PHASES-FILES: 15: offload, "host-sycl (x86_64-unknown-linux-gnu)" {11}, "device-sycl (spir64-unknown-unknown-sycldevice)" {14}, cpp-output +// CHK-PHASES-FILES: 15: offload, "host-sycl (x86_64-unknown-linux-gnu)" {11}, "device-sycl (spir64-unknown-unknown-sycldevice)" {14}, c++-cpp-output // CHK-PHASES-FILES: 16: compiler, {15}, ir, (host-sycl) // CHK-PHASES-FILES: 17: backend, {16}, assembler, (host-sycl) // CHK-PHASES-FILES: 18: assembler, {17}, object, (host-sycl) @@ -279,14 +279,14 @@ /// Check separate compilation with offloading - bundling actions // RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -c -o %t.o -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-BUACTIONS %s -// CHK-BUACTIONS: 0: input, "[[INPUT:.+\.c]]", c, (device-sycl) -// CHK-BUACTIONS: 1: preprocessor, {0}, cpp-output, (device-sycl) +// CHK-BUACTIONS: 0: input, "[[INPUT:.+\.c]]", c++, (device-sycl) +// CHK-BUACTIONS: 1: preprocessor, {0}, c++-cpp-output, (device-sycl) // CHK-BUACTIONS: 2: compiler, {1}, ir, (device-sycl) // CHK-BUACTIONS: 3: offload, "device-sycl (spir64-unknown-unknown-sycldevice)" {2}, ir -// CHK-BUACTIONS: 4: input, "[[INPUT]]", c, (host-sycl) -// CHK-BUACTIONS: 5: preprocessor, {4}, cpp-output, (host-sycl) +// CHK-BUACTIONS: 4: input, "[[INPUT]]", c++, (host-sycl) +// CHK-BUACTIONS: 5: preprocessor, {4}, c++-cpp-output, (host-sycl) // CHK-BUACTIONS: 6: compiler, {1}, sycl-header, (device-sycl) -// CHK-BUACTIONS: 7: offload, "host-sycl (x86_64-unknown-linux-gnu)" {5}, "device-sycl (spir64-unknown-unknown-sycldevice)" {6}, cpp-output +// CHK-BUACTIONS: 7: offload, "host-sycl (x86_64-unknown-linux-gnu)" {5}, "device-sycl (spir64-unknown-unknown-sycldevice)" {6}, c++-cpp-output // CHK-BUACTIONS: 8: compiler, {7}, ir, (host-sycl) // CHK-BUACTIONS: 9: backend, {8}, assembler, (host-sycl) // CHK-BUACTIONS: 10: assembler, {9}, object, (host-sycl) @@ -296,11 +296,11 @@ /// Check separate compilation with offloading - unbundling actions // RUN: touch %t.o -// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -o %t.out -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %t.o 2>&1 \ +// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -o %t.out -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %t.o 2>&1 \ // RUN: | FileCheck -DINPUT=%t.o -check-prefix=CHK-UBACTIONS %s // RUN: mkdir -p %t_dir // RUN: touch %t_dir/dummy -// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -o %t.out -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %t_dir/dummy 2>&1 \ +// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -o %t.out -lsomelib -fsycl-targets=spir64-unknown-unknown-sycldevice %t_dir/dummy 2>&1 \ // RUN: | FileCheck -DINPUT=%t_dir/dummy -check-prefix=CHK-UBACTIONS %s // CHK-UBACTIONS: 0: input, "somelib", object, (host-sycl) // CHK-UBACTIONS: 1: input, "[[INPUT]]", object, (host-sycl) @@ -318,17 +318,17 @@ /// Check separate compilation with offloading - unbundling with source // RUN: touch %t.o -// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -lsomelib -fsycl %t.o -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -lsomelib -fsycl -fno-sycl-device-lib=all %t.o -fsycl-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-UBUACTIONS %s // CHK-UBUACTIONS: 0: input, "somelib", object, (host-sycl) // CHK-UBUACTIONS: 1: input, "[[INPUT1:.+\.o]]", object, (host-sycl) // CHK-UBUACTIONS: 2: clang-offload-unbundler, {1}, object, (host-sycl) -// CHK-UBUACTIONS: 3: input, "[[INPUT2:.+\.c]]", c, (host-sycl) -// CHK-UBUACTIONS: 4: preprocessor, {3}, cpp-output, (host-sycl) -// CHK-UBUACTIONS: 5: input, "[[INPUT2]]", c, (device-sycl) -// CHK-UBUACTIONS: 6: preprocessor, {5}, cpp-output, (device-sycl) +// CHK-UBUACTIONS: 3: input, "[[INPUT2:.+\.c]]", c++, (host-sycl) +// CHK-UBUACTIONS: 4: preprocessor, {3}, c++-cpp-output, (host-sycl) +// CHK-UBUACTIONS: 5: input, "[[INPUT2]]", c++, (device-sycl) +// CHK-UBUACTIONS: 6: preprocessor, {5}, c++-cpp-output, (device-sycl) // CHK-UBUACTIONS: 7: compiler, {6}, sycl-header, (device-sycl) -// CHK-UBUACTIONS: 8: offload, "host-sycl (x86_64-unknown-linux-gnu)" {4}, "device-sycl (spir64-unknown-unknown-sycldevice)" {7}, cpp-output +// CHK-UBUACTIONS: 8: offload, "host-sycl (x86_64-unknown-linux-gnu)" {4}, "device-sycl (spir64-unknown-unknown-sycldevice)" {7}, c++-cpp-output // CHK-UBUACTIONS: 9: compiler, {8}, ir, (host-sycl) // CHK-UBUACTIONS: 10: backend, {9}, assembler, (host-sycl) // CHK-UBUACTIONS: 11: assembler, {10}, object, (host-sycl) @@ -405,8 +405,8 @@ // RUN: | FileCheck -check-prefix=CHK-LINK-TARGETS %s // RUN: %clang_cl -### -ccc-print-phases -fsycl -o %t.out -fsycl-link-targets=spir64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-LINK-TARGETS %s -// CHK-LINK-TARGETS: 0: input, "[[INPUT:.+\.c]]", c, (device-sycl) -// CHK-LINK-TARGETS: 1: preprocessor, {0}, cpp-output, (device-sycl) +// CHK-LINK-TARGETS: 0: input, "[[INPUT:.+\.c]]", c++, (device-sycl) +// CHK-LINK-TARGETS: 1: preprocessor, {0}, c++-cpp-output, (device-sycl) // CHK-LINK-TARGETS: 2: compiler, {1}, ir, (device-sycl) // CHK-LINK-TARGETS: 3: linker, {2}, image, (device-sycl) // CHK-LINK-TARGETS: 4: llvm-spirv, {3}, image, (device-sycl) @@ -435,8 +435,8 @@ // RUN: | FileCheck -check-prefix=CHK-LINK %s // RUN: %clang_cl -### -ccc-print-phases -fsycl -o %t.out -fsycl-link %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-LINK %s -// CHK-LINK: 0: input, "[[INPUT:.+\.c]]", c, (device-sycl) -// CHK-LINK: 1: preprocessor, {0}, cpp-output, (device-sycl) +// CHK-LINK: 0: input, "[[INPUT:.+\.c]]", c++, (device-sycl) +// CHK-LINK: 1: preprocessor, {0}, c++-cpp-output, (device-sycl) // CHK-LINK: 2: compiler, {1}, ir, (device-sycl) // CHK-LINK: 3: linker, {2}, image, (device-sycl) // CHK-LINK: 4: sycl-post-link, {3}, ir, (device-sycl) @@ -463,12 +463,12 @@ // RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -o %t.out -fsycl-add-targets=spir64-unknown-unknown-sycldevice:dummy.spv,spir64_fpga-unknown-unknown-sycldevice:dummy.aocx,spir64_gen-unknown-unknown-sycldevice:dummy_Gen9core.bin %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-ADD-TARGETS-MUL %s -// CHK-ADD-TARGETS-MUL: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-ADD-TARGETS-MUL: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-ADD-TARGETS-MUL: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-ADD-TARGETS-MUL: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-ADD-TARGETS-MUL: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-ADD-TARGETS-MUL: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-ADD-TARGETS-MUL: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-ADD-TARGETS-MUL: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-ADD-TARGETS-MUL: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-ADD-TARGETS-MUL: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-ADD-TARGETS-MUL: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-ADD-TARGETS-MUL: 6: compiler, {5}, ir, (host-sycl) // CHK-ADD-TARGETS-MUL: 7: backend, {6}, assembler, (host-sycl) // CHK-ADD-TARGETS-MUL: 8: assembler, {7}, object, (host-sycl) @@ -486,12 +486,12 @@ // RUN: %clang -### -ccc-print-phases -target x86_64-unknown-linux-gnu -fsycl -o %t.out -fsycl-add-targets=spir64-unknown-unknown-sycldevice:dummy0.spv,spir64-unknown-unknown-sycldevice:dummy1.spv,spir64-unknown-unknown-sycldevice:dummy2.spv %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-ADD-TARGETS-MUL-BINS %s -// CHK-ADD-TARGETS-MUL-BINS: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-ADD-TARGETS-MUL-BINS: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-ADD-TARGETS-MUL-BINS: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-ADD-TARGETS-MUL-BINS: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-ADD-TARGETS-MUL-BINS: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-ADD-TARGETS-MUL-BINS: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-ADD-TARGETS-MUL-BINS: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-ADD-TARGETS-MUL-BINS: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-ADD-TARGETS-MUL-BINS: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-ADD-TARGETS-MUL-BINS: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-ADD-TARGETS-MUL-BINS: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-ADD-TARGETS-MUL-BINS: 6: compiler, {5}, ir, (host-sycl) // CHK-ADD-TARGETS-MUL-BINS: 7: backend, {6}, assembler, (host-sycl) // CHK-ADD-TARGETS-MUL-BINS: 8: assembler, {7}, object, (host-sycl) @@ -508,14 +508,14 @@ /// Check regular offload with an additional AOT binary passed through -fsycl-add-targets (same triple) -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice -fsycl-add-targets=spir64-unknown-unknown-sycldevice:dummy.spv -ccc-print-phases %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64-unknown-unknown-sycldevice -fsycl-add-targets=spir64-unknown-unknown-sycldevice:dummy.spv -ccc-print-phases %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-ADD-TARGETS-REG %s -// CHK-ADD-TARGETS-REG: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-ADD-TARGETS-REG: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-ADD-TARGETS-REG: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-ADD-TARGETS-REG: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-ADD-TARGETS-REG: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-ADD-TARGETS-REG: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-ADD-TARGETS-REG: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-ADD-TARGETS-REG: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-ADD-TARGETS-REG: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-ADD-TARGETS-REG: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-ADD-TARGETS-REG: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-ADD-TARGETS-REG: 6: compiler, {5}, ir, (host-sycl) // CHK-ADD-TARGETS-REG: 7: backend, {6}, assembler, (host-sycl) // CHK-ADD-TARGETS-REG: 8: assembler, {7}, object, (host-sycl) @@ -534,20 +534,20 @@ /// ########################################################################### /// Check regular offload with multiple additional AOT binaries passed through -fsycl-add-targets -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice -fsycl-add-targets=spir64_fpga-unknown-unknown-sycldevice:dummy.aocx,spir64_gen-unknown-unknown-sycldevice:dummy_Gen9core.bin,spir64_x86_64-unknown-unknown-sycldevice:dummy.ir -ccc-print-phases %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64-unknown-unknown-sycldevice -fsycl-add-targets=spir64_fpga-unknown-unknown-sycldevice:dummy.aocx,spir64_gen-unknown-unknown-sycldevice:dummy_Gen9core.bin,spir64_x86_64-unknown-unknown-sycldevice:dummy.ir -ccc-print-phases %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-ADD-TARGETS-REG-MUL %s -// CHK-ADD-TARGETS-REG-MUL: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-ADD-TARGETS-REG-MUL: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-ADD-TARGETS-REG-MUL: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-ADD-TARGETS-REG-MUL: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-ADD-TARGETS-REG-MUL: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-ADD-TARGETS-REG-MUL: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-ADD-TARGETS-REG-MUL: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-ADD-TARGETS-REG-MUL: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-ADD-TARGETS-REG-MUL: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-ADD-TARGETS-REG-MUL: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64{{.*}}-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-ADD-TARGETS-REG-MUL: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64{{.*}}-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-ADD-TARGETS-REG-MUL: 6: compiler, {5}, ir, (host-sycl) // CHK-ADD-TARGETS-REG-MUL: 7: backend, {6}, assembler, (host-sycl) // CHK-ADD-TARGETS-REG-MUL: 8: assembler, {7}, object, (host-sycl) // CHK-ADD-TARGETS-REG-MUL: 9: linker, {8}, image, (host-sycl) -// CHK-ADD-TARGETS-REG-MUL: 10: input, "[[INPUT]]", c, (device-sycl) -// CHK-ADD-TARGETS-REG-MUL: 11: preprocessor, {10}, cpp-output, (device-sycl) +// CHK-ADD-TARGETS-REG-MUL: 10: input, "[[INPUT]]", c++, (device-sycl) +// CHK-ADD-TARGETS-REG-MUL: 11: preprocessor, {10}, c++-cpp-output, (device-sycl) // CHK-ADD-TARGETS-REG-MUL: 12: compiler, {11}, ir, (device-sycl) // CHK-ADD-TARGETS-REG-MUL: 13: linker, {12}, ir, (device-sycl) // CHK-ADD-TARGETS-REG-MUL: 14: sycl-post-link, {13}, tempfiletable, (device-sycl) @@ -577,21 +577,22 @@ /// Check for default linking of sycl.lib with -fsycl usage // RUN: %clang -fsycl -target x86_64-unknown-windows-msvc %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-SYCL %s -// RUN: %clang_cl -fsycl %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-SYCL %s -// CHECK-LINK-SYCL: "{{.*}}link{{(.exe)?}}" +// RUN: %clang_cl -fsycl %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-SYCL-CL %s +// CHECK-LINK-SYCL-CL: "--dependent-lib=sycl" +// CHECK-LINK-SYCL-CL-NOT: "-defaultlib:sycl.lib" // CHECK-LINK-SYCL: "-defaultlib:sycl.lib" /// Check no SYCL runtime is linked with -nolibsycl // RUN: %clang -fsycl -nolibsycl -target x86_64-unknown-windows-msvc %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-NOLIBSYCL %s // RUN: %clang_cl -fsycl -nolibsycl %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-NOLIBSYCL %s +// CHECK-LINK-NOLIBSYCL-NOT: "--dependent-lib=sycl" // CHECK-LINK-NOLIBSYCL: "{{.*}}link{{(.exe)?}}" // CHECK-LINK-NOLIBSYCL-NOT: "-defaultlib:sycl.lib" -/// Check sycld.lib is chosen with /MDd and /MTd +/// Check sycld.lib is chosen with /MDd // RUN: %clang_cl -fsycl /MDd %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-SYCL-DEBUG %s -// RUN: %clang_cl -fsycl /MTd %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-SYCL-DEBUG %s -// CHECK-LINK-SYCL-DEBUG: "{{.*}}link{{(.exe)?}}" -// CHECK-LINK-SYCL-DEBUG: "-defaultlib:sycld.lib" +// CHECK-LINK-SYCL-DEBUG: "--dependent-lib=sycld" +// CHECK-LINK-SYCL-DEBUG-NOT: "-defaultlib:sycld.lib" /// Check "-spirv-allow-unknown-intrinsics" option is emitted for llvm-spirv tool for esimd mode // RUN: %clangxx %s -fsycl -fsycl-explicit-simd -### 2>&1 | FileCheck %s --check-prefix=CHK-FSYCL-ESIMD @@ -609,20 +610,20 @@ /// ########################################################################### /// Ahead of Time compilation for fpga, gen, cpu -// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-PHASES-AOT,CHK-PHASES-FPGA -// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-PHASES-AOT,CHK-PHASES-GEN -// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-PHASES-AOT,CHK-PHASES-CPU -// CHK-PHASES-AOT: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-PHASES-AOT: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-PHASES-AOT: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASES-AOT: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-PHASES-AOT: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-PHASES-AOT: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-PHASES-AOT: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASES-AOT: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-PHASES-AOT: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-PHASES-FPGA: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, cpp-output -// CHK-PHASES-GEN: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_gen-unknown-unknown-sycldevice)" {4}, cpp-output -// CHK-PHASES-CPU: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_x86_64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-PHASES-FPGA: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, c++-cpp-output +// CHK-PHASES-GEN: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_gen-unknown-unknown-sycldevice)" {4}, c++-cpp-output +// CHK-PHASES-CPU: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_x86_64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-PHASES-AOT: 6: compiler, {5}, ir, (host-sycl) // CHK-PHASES-AOT: 7: backend, {6}, assembler, (host-sycl) // CHK-PHASES-AOT: 8: assembler, {7}, object, (host-sycl) @@ -642,29 +643,29 @@ /// ########################################################################### /// Ahead of Time compilation for fpga, gen, cpu - tool invocation -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA,CHK-TOOLS-FPGA-USM-DISABLE -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA,CHK-TOOLS-FPGA-USM-DISABLE -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice -Xshardware %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice -Xshardware %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA,CHK-TOOLS-FPGA-USM-ENABLE -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -Xshardware %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -Xshardware %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA,CHK-TOOLS-FPGA-USM-ENABLE -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice -Xssimulation %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice -Xssimulation %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA,CHK-TOOLS-FPGA-USM-ENABLE -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -Xssimulation %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -Xssimulation %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA,CHK-TOOLS-FPGA-USM-ENABLE -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice -Xsemulator %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice -Xsemulator %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA,CHK-TOOLS-FPGA-USM-DISABLE -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -Xsemulator %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -Xsemulator %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-FPGA,CHK-TOOLS-FPGA-USM-DISABLE -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-GEN -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-CPU -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-GEN -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-AOT,CHK-TOOLS-CPU // CHK-TOOLS-AOT: clang{{.*}} "-fsycl-is-device" {{.*}} "-o" "[[OUTPUT1:.+\.bc]]" // CHK-TOOLS-AOT: llvm-link{{.*}} "[[OUTPUT1]]" "-o" "[[OUTPUT2:.+\.bc]]" @@ -689,10 +690,16 @@ // Check to be sure that for windows, the 'exe' tools are called // RUN: %clang_cl -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-CPU-WIN +// RUN: %clang -target x86_64-pc-windows-msvc -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-CPU-WIN // RUN: %clang_cl -fsycl -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-GEN-WIN +// RUN: %clang -target x86_64-pc-windows-msvc -fsycl -fsycl-targets=spir64_gen-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-GEN-WIN // RUN: %clang_cl -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s -### 2>&1 \ // RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-FPGA-WIN +// RUN: %clang -target x86_64-pc-windows-msvc -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s -### 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=CHK-TOOLS-FPGA-WIN // CHK-TOOLS-GEN-WIN: ocloc.exe{{.*}} // CHK-TOOLS-CPU-WIN: opencl-aot.exe{{.*}} // CHK-TOOLS-FPGA-WIN: aoc.exe{{.*}} @@ -785,20 +792,20 @@ /// ########################################################################### /// offload with multiple targets, including AOT -// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice,spir64_fpga-unknown-unknown-sycldevice,spir64_gen-unknown-unknown-sycldevice -### -ccc-print-phases %s 2>&1 \ +// RUN: %clang -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64-unknown-unknown-sycldevice,spir64_fpga-unknown-unknown-sycldevice,spir64_gen-unknown-unknown-sycldevice -### -ccc-print-phases %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-PHASE-MULTI-TARG %s -// CHK-PHASE-MULTI-TARG: 0: input, "[[INPUT:.+\.c]]", c, (host-sycl) -// CHK-PHASE-MULTI-TARG: 1: preprocessor, {0}, cpp-output, (host-sycl) -// CHK-PHASE-MULTI-TARG: 2: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASE-MULTI-TARG: 3: preprocessor, {2}, cpp-output, (device-sycl) +// CHK-PHASE-MULTI-TARG: 0: input, "[[INPUT:.+\.c]]", c++, (host-sycl) +// CHK-PHASE-MULTI-TARG: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHK-PHASE-MULTI-TARG: 2: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASE-MULTI-TARG: 3: preprocessor, {2}, c++-cpp-output, (device-sycl) // CHK-PHASE-MULTI-TARG: 4: compiler, {3}, sycl-header, (device-sycl) -// CHK-PHASE-MULTI-TARG: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, cpp-output +// CHK-PHASE-MULTI-TARG: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown-sycldevice)" {4}, c++-cpp-output // CHK-PHASE-MULTI-TARG: 6: compiler, {5}, ir, (host-sycl) // CHK-PHASE-MULTI-TARG: 7: backend, {6}, assembler, (host-sycl) // CHK-PHASE-MULTI-TARG: 8: assembler, {7}, object, (host-sycl) // CHK-PHASE-MULTI-TARG: 9: linker, {8}, image, (host-sycl) -// CHK-PHASE-MULTI-TARG: 10: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASE-MULTI-TARG: 11: preprocessor, {10}, cpp-output, (device-sycl) +// CHK-PHASE-MULTI-TARG: 10: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASE-MULTI-TARG: 11: preprocessor, {10}, c++-cpp-output, (device-sycl) // CHK-PHASE-MULTI-TARG: 12: compiler, {11}, ir, (device-sycl) // CHK-PHASE-MULTI-TARG: 13: linker, {12}, ir, (device-sycl) // CHK-PHASE-MULTI-TARG: 14: sycl-post-link, {13}, tempfiletable, (device-sycl) @@ -806,8 +813,8 @@ // CHK-PHASE-MULTI-TARG: 16: llvm-spirv, {15}, tempfilelist, (device-sycl) // CHK-PHASE-MULTI-TARG: 17: file-table-tform, {14, 16}, tempfiletable, (device-sycl) // CHK-PHASE-MULTI-TARG: 18: clang-offload-wrapper, {17}, object, (device-sycl) -// CHK-PHASE-MULTI-TARG: 19: input, "[[INPUT]]", c, (device-sycl) -// CHK-PHASE-MULTI-TARG: 20: preprocessor, {19}, cpp-output, (device-sycl) +// CHK-PHASE-MULTI-TARG: 19: input, "[[INPUT]]", c++, (device-sycl) +// CHK-PHASE-MULTI-TARG: 20: preprocessor, {19}, c++-cpp-output, (device-sycl) // CHK-PHASE-MULTI-TARG: 21: compiler, {20}, ir, (device-sycl) // CHK-PHASE-MULTI-TARG: 22: linker, {21}, ir, (device-sycl) // CHK-PHASE-MULTI-TARG: 23: sycl-post-link, {22}, ir, (device-sycl) @@ -824,9 +831,9 @@ /// ########################################################################### /// Verify that -save-temps does not crash -// RUN: %clang -fsycl -target x86_64-unknown-linux-gnu -save-temps %s -### 2>&1 -// RUN: %clang -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice -target x86_64-unknown-linux-gnu -save-temps %s -### 2>&1 -// RUN: %clangxx -fsycl -fsycl-targets=spir64-unknown-unknown-sycldevice -target x86_64-unknown-linux-gnu -save-temps %s -### 2>&1 \ +// RUN: %clang -fsycl -fno-sycl-device-lib=all -target x86_64-unknown-linux-gnu -save-temps %s -### 2>&1 +// RUN: %clang -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64-unknown-unknown-sycldevice -target x86_64-unknown-linux-gnu -save-temps %s -### 2>&1 +// RUN: %clangxx -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64-unknown-unknown-sycldevice -target x86_64-unknown-linux-gnu -save-temps %s -### 2>&1 \ // RUN: | FileCheck %s --check-prefixes=CHK-FSYCL-SAVE-TEMPS,CHK-FSYCL-SAVE-TEMPS-CONFL // CHK-FSYCL-SAVE-TEMPS: clang{{.*}} "-fsycl-is-device"{{.*}} "-o" "[[DEVICE_BASE_NAME:[a-z0-9-]+]].ii" // CHK-FSYCL-SAVE-TEMPS: clang{{.*}} "-fsycl-is-device"{{.*}} "-o" "[[DEVICE_BASE_NAME]].bc"{{.*}} "[[DEVICE_BASE_NAME]].ii" @@ -858,9 +865,9 @@ /// passing of a library should not trigger the unbundler // RUN: touch %t.a // RUN: touch %t.lib -// RUN: %clang -ccc-print-phases -fsycl %t.a %s 2>&1 \ +// RUN: %clang -ccc-print-phases -fsycl -fno-sycl-device-lib=all %t.a %s 2>&1 \ // RUN: | FileCheck -check-prefix=LIB-UNBUNDLE-CHECK %s -// RUN: %clang_cl -ccc-print-phases -fsycl %t.lib %s 2>&1 \ +// RUN: %clang_cl -ccc-print-phases -fsycl -fno-sycl-device-lib=all %t.lib %s 2>&1 \ // RUN: | FileCheck -check-prefix=LIB-UNBUNDLE-CHECK %s // LIB-UNBUNDLE-CHECK-NOT: clang-offload-unbundler @@ -879,7 +886,8 @@ // Checking for an error if c-compilation is forced // RUN: %clangxx -### -c -fsycl -xc %s 2>&1 | FileCheck -check-prefixes=CHECK_XC_FSYCL %s // RUN: %clangxx -### -c -fsycl -xc-header %s 2>&1 | FileCheck -check-prefixes=CHECK_XC_FSYCL %s -// CHECK_XC_FSYCL: The option -x c{{.*}} must not be used in conjunction with -fsycl{{.*}} +// RUN: %clangxx -### -c -fsycl -xcpp-output %s 2>&1 | FileCheck -check-prefixes=CHECK_XC_FSYCL %s +// CHECK_XC_FSYCL: The option '-x c{{.*}}' must not be used in conjunction with '-fsycl' // -std=c++17 check (check all 3 compilations) // RUN: %clangxx -### -c -fsycl -xc++ %s 2>&1 | FileCheck -check-prefix=CHECK-STD %s @@ -891,7 +899,9 @@ // -std=c++17 override check // RUN: %clangxx -### -c -fsycl -std=c++14 -xc++ %s 2>&1 | FileCheck -check-prefix=CHECK-STD-OVR %s // RUN: %clang_cl -### -c -fsycl /std:c++14 -TP %s 2>&1 | FileCheck -check-prefix=CHECK-STD-OVR %s -// CHECK-STD-OVR: clang{{.*}} "-std=c++14" +// CHECK-STD-OVR: clang{{.*}} "-emit-llvm-bc" {{.*}} "-std=c++14" +// CHECK-STD-OVR: clang{{.*}} "-fsyntax-only" {{.*}} "-std=c++14" +// CHECK-STD-OVR: clang{{.*}} "-emit-obj" {{.*}} "-std=c++14" // CHECK-STD-OVR-NOT: clang{{.*}} "-std=c++17" // TODO: SYCL specific fail - analyze and enable diff --git a/clang/test/Driver/sycl.c b/clang/test/Driver/sycl.c index 13c8fc0592690..33a04d091c98a 100644 --- a/clang/test/Driver/sycl.c +++ b/clang/test/Driver/sycl.c @@ -75,7 +75,7 @@ // SYCL-HELP-BADARG: unsupported argument 'foo' to option 'fsycl-help=' // SYCL-HELP-GEN: Emitting help information for ocloc // SYCL-HELP-GEN: Use triple of 'spir64_gen-unknown-unknown-sycldevice' to enable ahead of time compilation -// SYCL-HELP-FPGA-OUT: "[[DIR]]{{[/\\]+}}aoc" "-help" +// SYCL-HELP-FPGA-OUT: "[[DIR]]{{[/\\]+}}aoc" "-help" "-sycl" // SYCL-HELP-FPGA: Emitting help information for aoc // SYCL-HELP-FPGA: Use triple of 'spir64_fpga-unknown-unknown-sycldevice' to enable ahead of time compilation // SYCL-HELP-CPU: Emitting help information for opencl-aot diff --git a/clang/test/Driver/target-override.c b/clang/test/Driver/target-override.c index b4dbd2da1df6f..ddda8aaad85a0 100644 --- a/clang/test/Driver/target-override.c +++ b/clang/test/Driver/target-override.c @@ -1,16 +1,15 @@ // REQUIRES: shell // REQUIRES: x86-registered-target -// RUN: rm -rf %T/testbin -// RUN: mkdir -p %T/testbin -// RUN: ln -s %clang %T/testbin/i386-clang +// RUN: rm -rf %t && mkdir %t +// RUN: ln -s %clang %t/i386-clang // Check if invocation of "foo-clang" adds option "-target foo". // -// RUN: %T/testbin/i386-clang -c -no-canonical-prefixes %s -### 2>&1 | FileCheck -check-prefix CHECK-TG1 %s +// RUN: %t/i386-clang -c -no-canonical-prefixes %s -### 2>&1 | FileCheck -check-prefix CHECK-TG1 %s // CHECK-TG1: Target: i386 // Check if invocation of "foo-clang -target bar" overrides option "-target foo". // -// RUN: %T/testbin/i386-clang -c -no-canonical-prefixes -target x86_64 %s -### 2>&1 | FileCheck -check-prefix CHECK-TG2 %s +// RUN: %t/i386-clang -c -no-canonical-prefixes -target x86_64 %s -### 2>&1 | FileCheck -check-prefix CHECK-TG2 %s // CHECK-TG2: Target: x86_64 diff --git a/clang/test/Format/dump-config-list-override.cpp b/clang/test/Format/dump-config-list-override.cpp new file mode 100644 index 0000000000000..df4c6ad1333ef --- /dev/null +++ b/clang/test/Format/dump-config-list-override.cpp @@ -0,0 +1,24 @@ +/// Check that the ForEachMacros, etc. config entries replace default values instead of appending +/// FIXME: clang-format currently start overriding at index 0 (keeping the remaining +/// values) instead of either appending or completely replacing the values. +/// This behaviour is highly confusing. For now this test documents the current state. +// RUN: clang-format -style="{BasedOnStyle: LLVM}" -dump-config %s | \ +// RUN: FileCheck %s --check-prefixes=CHECK,DEFAULT +// RUN: clang-format -style="{BasedOnStyle: LLVM, ForEachMacros: ['OVERRIDE_FOREACH']}" -dump-config %s | \ +// RUN: FileCheck %s --check-prefixes=CHECK,OVERRIDE,FIXME-SHOULD-NOT-BE +// RUN: clang-format -style="{BasedOnStyle: LLVM, ForEachMacros: ['M1', 'M2', 'M3', 'M4']}" -dump-config %s | \ +// RUN: FileCheck %s --check-prefixes=CHECK,MORE-ENTRIES-THAN-DEFAULT + + +// CHECK-LABEL: ForEachMacros: +// DEFAULT-NEXT: {{^ }}- foreach +// DEFAULT-NEXT: {{^ }}- Q_FOREACH +// DEFAULT-NEXT: {{^ }}- BOOST_FOREACH +// OVERRIDE-NEXT: {{^ }}- OVERRIDE_FOREACH +// FIXME-SHOULD-NOT-BE-NEXT: {{^ }}- Q_FOREACH +// FIXME-SHOULD-NOT-BE-NEXT: {{^ }}- BOOST_FOREACH +// MORE-ENTRIES-THAN-DEFAULT-NEXT: {{^ }}- M1 +// MORE-ENTRIES-THAN-DEFAULT-NEXT: {{^ }}- M2 +// MORE-ENTRIES-THAN-DEFAULT-NEXT: {{^ }}- M3 +// MORE-ENTRIES-THAN-DEFAULT-NEXT: {{^ }}- M4 +// CHECK-NEXT: {{^[F-Z]}} diff --git a/clang/test/PCH/cxx1z-decomposition.cpp b/clang/test/PCH/cxx1z-decomposition.cpp index 2f817b4280ded..914ce80c550d1 100644 --- a/clang/test/PCH/cxx1z-decomposition.cpp +++ b/clang/test/PCH/cxx1z-decomposition.cpp @@ -2,11 +2,11 @@ // RUN: %clang_cc1 -pedantic -std=c++1z -include %s -verify %s // // With PCH: -// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch %s -o %t -// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch -fallow-pch-with-compiler-errors %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -fallow-pch-with-compiler-errors -verify %s -// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch -fpch-instantiate-templates %s -o %t -// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch -fallow-pch-with-compiler-errors -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -fallow-pch-with-compiler-errors -verify %s #ifndef HEADER #define HEADER @@ -22,6 +22,8 @@ constexpr int foo(Q &&q) { return a * 10 + b; } +auto [noinit]; // expected-error{{decomposition declaration '[noinit]' requires an initializer}} + #else int arr[2]; diff --git a/clang/test/Parser/pragma-fenv_round.c b/clang/test/Parser/pragma-fenv_round.c new file mode 100644 index 0000000000000..56abf7bf75a40 --- /dev/null +++ b/clang/test/Parser/pragma-fenv_round.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -Wignored-pragmas -verify %s + +#pragma STDC FENV_ROUND ON // expected-warning {{invalid or unsupported rounding mode}} + +float func_01(int x, float y) { + if (x) + return y + 2; + #pragma STDC FENV_ROUND FE_DOWNWARD // expected-error{{'#pragma STDC FENV_ROUND' can only appear at file scope or at the start of a compound statement}} + // expected-warning@-1{{pragma STDC FENV_ROUND is not supported}} + return x + y; +} diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 905a77785a9d8..cb137eea072e6 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -44,12 +44,12 @@ // CHECK-NOT: __ARM_BF16_FORMAT_ALTERNATIVE 1 // CHECK-NOT: __ARM_FEATURE_BF16 1 // CHECK-NOT: __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1 -// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 0 -// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 128 -// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 256 -// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 512 -// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 1024 -// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 2048 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS 0 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS 128 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS 256 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS 512 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS 1024 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS 2048 // RUN: %clang -target aarch64_be-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-BIGENDIAN // CHECK-BIGENDIAN: __ARM_BIG_ENDIAN 1 @@ -444,10 +444,8 @@ // RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=1024 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-1024 %s // RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=2048 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-2048 %s // RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=2048 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-2048 %s -// NOTE: The __ARM_FEATURE_SVE_BITS feature macro is experimental until the -// feature is complete. -// CHECK-SVE-VECTOR-BITS-128: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 128 -// CHECK-SVE-VECTOR-BITS-256: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 256 -// CHECK-SVE-VECTOR-BITS-512: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 512 -// CHECK-SVE-VECTOR-BITS-1024: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 1024 -// CHECK-SVE-VECTOR-BITS-2048: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 2048 +// CHECK-SVE-VECTOR-BITS-128: __ARM_FEATURE_SVE_BITS 128 +// CHECK-SVE-VECTOR-BITS-256: __ARM_FEATURE_SVE_BITS 256 +// CHECK-SVE-VECTOR-BITS-512: __ARM_FEATURE_SVE_BITS 512 +// CHECK-SVE-VECTOR-BITS-1024: __ARM_FEATURE_SVE_BITS 1024 +// CHECK-SVE-VECTOR-BITS-2048: __ARM_FEATURE_SVE_BITS 2048 diff --git a/clang/test/Sema/attr-arm-sve-vector-bits.c b/clang/test/Sema/attr-arm-sve-vector-bits.c index f143037fd6114..1bcbfa360c976 100644 --- a/clang/test/Sema/attr-arm-sve-vector-bits.c +++ b/clang/test/Sema/attr-arm-sve-vector-bits.c @@ -4,7 +4,7 @@ // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -msve-vector-bits=1024 -fallow-half-arguments-and-returns %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -msve-vector-bits=2048 -fallow-half-arguments-and-returns %s -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef __SVInt8_t svint8_t; typedef __SVInt16_t svint16_t; diff --git a/clang/test/SemaCXX/attr-arm-sve-vector-bits.cpp b/clang/test/SemaCXX/attr-arm-sve-vector-bits.cpp index c8ce257ad3265..ea7c4778db0ea 100644 --- a/clang/test/SemaCXX/attr-arm-sve-vector-bits.cpp +++ b/clang/test/SemaCXX/attr-arm-sve-vector-bits.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -std=c++11 -msve-vector-bits=512 -fallow-half-arguments-and-returns %s // expected-no-diagnostics -#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL +#define N __ARM_FEATURE_SVE_BITS typedef __SVInt8_t svint8_t; typedef svint8_t fixed_int8_t __attribute__((arm_sve_vector_bits(N))); diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp index 06771f8f3252a..5b5d1cb7bc807 100644 --- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp +++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp @@ -23,6 +23,10 @@ static_assert(sizeof(long long) == 8); template constexpr To bit_cast(const From &from) { static_assert(sizeof(To) == sizeof(From)); + // expected-note@+9 {{cannot be represented in type 'bool'}} +#ifdef __x86_64 + // expected-note@+7 {{or 'std::byte'; '__int128' is invalid}} +#endif #ifdef __CHAR_UNSIGNED__ // expected-note@+4 2 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'signed char' is invalid}} #else @@ -397,3 +401,65 @@ union IdentityInUnion { }; constexpr IdentityInUnion identity3a = {42}; constexpr unsigned char identity3b = __builtin_bit_cast(unsigned char, identity3a.n); + +namespace test_bool { + +constexpr bool test_bad_bool = bit_cast('A'); // expected-error {{must be initialized by a constant expression}} expected-note{{in call}} + +static_assert(round_trip(true), ""); +static_assert(round_trip(false), ""); +static_assert(round_trip(false), ""); + +static_assert(round_trip((char)0), ""); +static_assert(round_trip((char)1), ""); +} + +namespace test_long_double { +#ifdef __x86_64 +constexpr __int128_t test_cast_to_int128 = bit_cast<__int128_t>((long double)0); // expected-error{{must be initialized by a constant expression}} expected-note{{in call}} + +constexpr long double ld = 3.1425926539; + +struct bytes { + unsigned char d[16]; +}; + +static_assert(round_trip(ld), ""); + +static_assert(round_trip(10.0L)); + +constexpr bool f(bool read_uninit) { + bytes b = bit_cast(ld); + unsigned char ld_bytes[10] = { + 0x0, 0x48, 0x9f, 0x49, 0xf0, + 0x3c, 0x20, 0xc9, 0x0, 0x40, + }; + + for (int i = 0; i != 10; ++i) + if (ld_bytes[i] != b.d[i]) + return false; + + if (read_uninit && b.d[10]) // expected-note{{read of uninitialized object is not allowed in a constant expression}} + return false; + + return true; +} + +static_assert(f(/*read_uninit=*/false), ""); +static_assert(f(/*read_uninit=*/true), ""); // expected-error{{static_assert expression is not an integral constant expression}} expected-note{{in call to 'f(true)'}} + +constexpr bytes ld539 = { + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc0, 0x86, + 0x8, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, +}; + +constexpr long double fivehundredandthirtynine = 539.0; + +static_assert(bit_cast(ld539) == fivehundredandthirtynine, ""); + +#else +static_assert(round_trip<__int128_t>(34.0L)); +#endif +} diff --git a/clang/test/SemaCXX/thread-safety-annotations.h b/clang/test/SemaCXX/thread-safety-annotations.h index 7755a1b328e7e..d89bcf8ff4706 100644 --- a/clang/test/SemaCXX/thread-safety-annotations.h +++ b/clang/test/SemaCXX/thread-safety-annotations.h @@ -6,6 +6,7 @@ #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_capability(__VA_ARGS__))) #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((acquire_capability(__VA_ARGS__))) #define SHARED_LOCK_FUNCTION(...) __attribute__((acquire_shared_capability(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__((release_generic_capability(__VA_ARGS__))) #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_capability(__VA_ARGS__))) #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_shared_capability(__VA_ARGS__))) #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((requires_capability(__VA_ARGS__))) @@ -16,6 +17,7 @@ #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_lock(__VA_ARGS__))) #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__))) #define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__))) #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__))) #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__VA_ARGS__))) @@ -23,7 +25,6 @@ #endif // Lock semantics only -#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) #define GUARDED_VAR __attribute__((guarded_var)) #define PT_GUARDED_VAR __attribute__((pt_guarded_var)) diff --git a/clang/test/SemaCXX/unreachable-code.cpp b/clang/test/SemaCXX/unreachable-code.cpp index fd006c099e7dc..0dfc3d5744fb3 100644 --- a/clang/test/SemaCXX/unreachable-code.cpp +++ b/clang/test/SemaCXX/unreachable-code.cpp @@ -68,3 +68,12 @@ int pr6130(unsigned i) { throw PR6130(); // no-warning } } + +extern "C" void foo(void); +extern "C" __attribute__((weak)) decltype(foo) foo; + +void weak_redecl() { + if (foo) + return; + bar(); // no-warning +} diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index 91bd15def577d..d1520b1decbd3 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5036,7 +5036,8 @@ void spawn_fake_flight_control_thread(void) { } extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger))); -void logger_entry(void) __attribute__((requires_capability(Logger))) { +void logger_entry(void) __attribute__((requires_capability(Logger))) + __attribute__((requires_capability(!FlightControl))) { const char *msg; while ((msg = deque_log_msg())) { @@ -5044,13 +5045,13 @@ void logger_entry(void) __attribute__((requires_capability(Logger))) { } } -void spawn_fake_logger_thread(void) { +void spawn_fake_logger_thread(void) __attribute__((requires_capability(!FlightControl))) { acquire(Logger); logger_entry(); release(Logger); } -int main(void) { +int main(void) __attribute__((requires_capability(!FlightControl))) { spawn_fake_flight_control_thread(); spawn_fake_logger_thread(); diff --git a/clang/test/SemaCXX/warn-thread-safety-negative.cpp b/clang/test/SemaCXX/warn-thread-safety-negative.cpp index 456fe16e6574e..68e30f4a3225b 100644 --- a/clang/test/SemaCXX/warn-thread-safety-negative.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-negative.cpp @@ -81,6 +81,35 @@ class Foo { } // end namespace SimpleTest +Mutex globalMutex; + +namespace ScopeTest { + +void f() EXCLUSIVE_LOCKS_REQUIRED(!globalMutex); +void fq() EXCLUSIVE_LOCKS_REQUIRED(!::globalMutex); + +namespace ns { + Mutex globalMutex; + void f() EXCLUSIVE_LOCKS_REQUIRED(!globalMutex); + void fq() EXCLUSIVE_LOCKS_REQUIRED(!ns::globalMutex); +} + +void testGlobals() EXCLUSIVE_LOCKS_REQUIRED(!ns::globalMutex) { + f(); // expected-warning {{calling function 'f' requires negative capability '!globalMutex'}} + fq(); // expected-warning {{calling function 'fq' requires negative capability '!globalMutex'}} + ns::f(); + ns::fq(); +} + +void testNamespaceGlobals() EXCLUSIVE_LOCKS_REQUIRED(!globalMutex) { + f(); + fq(); + ns::f(); // expected-warning {{calling function 'f' requires negative capability '!globalMutex'}} + ns::fq(); // expected-warning {{calling function 'fq' requires negative capability '!globalMutex'}} +} + +} // end namespace ScopeTest + namespace DoubleAttribute { struct Foo { diff --git a/clang/test/SemaObjC/arc-repeated-weak.mm b/clang/test/SemaObjC/arc-repeated-weak.mm index 4eec4d2fe69c7..90388598c7b8d 100644 --- a/clang/test/SemaObjC/arc-repeated-weak.mm +++ b/clang/test/SemaObjC/arc-repeated-weak.mm @@ -485,3 +485,17 @@ void foo1() { @class NSString; static NSString* const kGlobal = @""; + +@interface NSDictionary +- (id)objectForKeyedSubscript:(id)key; +@end + +@interface WeakProp +@property (weak) NSDictionary *nd; +@end + +@implementation WeakProp +-(void)m { + (void)self.nd[@""]; // no warning +} +@end diff --git a/clang/test/SemaSYCL/Inputs/sycl.hpp b/clang/test/SemaSYCL/Inputs/sycl.hpp index 65a77b01f165a..f2bfe5e357041 100644 --- a/clang/test/SemaSYCL/Inputs/sycl.hpp +++ b/clang/test/SemaSYCL/Inputs/sycl.hpp @@ -37,13 +37,20 @@ enum class address_space : int { }; } // namespace access +class property_list {}; + +namespace INTEL { namespace property { -template -class buffer_location {}; +struct buffer_location { + template class instance {}; +}; } // namespace property +} // namespace INTEL +namespace ONEAPI { template -class property_list {}; +class accessor_property_list {}; +} // namespace ONEAPI namespace detail { namespace half_impl { @@ -95,7 +102,7 @@ struct DeviceValueType { template > + typename propertyListT = ONEAPI::accessor_property_list<>> class accessor { public: @@ -107,7 +114,6 @@ class accessor { using PtrType = typename DeviceValueType::type *; void __init(PtrType Ptr, range AccessRange, range MemRange, id Offset) {} - propertyListT prop_list; }; template diff --git a/clang/test/SemaSYCL/accessor_inheritance.cpp b/clang/test/SemaSYCL/accessor_inheritance.cpp index 78bdddda98945..b481d34f4ba70 100644 --- a/clang/test/SemaSYCL/accessor_inheritance.cpp +++ b/clang/test/SemaSYCL/accessor_inheritance.cpp @@ -42,8 +42,8 @@ int main() { // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_A' 'int' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_B' 'int' -// CHECK-NEXT: CXXConstructExpr {{.*}} 'cl::sycl::accessor':'cl::sycl::accessor>' 'void () noexcept' -// CHECK-NEXT: CXXConstructExpr {{.*}} 'cl::sycl::accessor':'cl::sycl::accessor>' 'void () noexcept' +// CHECK-NEXT: CXXConstructExpr {{.*}} 'cl::sycl::accessor':'cl::sycl::accessor>' 'void () noexcept' +// CHECK-NEXT: CXXConstructExpr {{.*}} 'cl::sycl::accessor':'cl::sycl::accessor>' 'void () noexcept' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_C' 'int' diff --git a/clang/test/SemaSYCL/args-size-overflow.cpp b/clang/test/SemaSYCL/args-size-overflow.cpp index efef20d8a96b0..d312b8f72316c 100644 --- a/clang/test/SemaSYCL/args-size-overflow.cpp +++ b/clang/test/SemaSYCL/args-size-overflow.cpp @@ -1,9 +1,8 @@ -// RUN: %clang_cc1 -fsycl -triple spir64_gen -DGPU -fsycl-is-device -fsyntax-only -verify %s // RUN: %clang_cc1 -fsycl -triple spir64 -fsycl-is-device -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsycl -triple spir64_gen -Wno-sycl-strict -fsycl-is-device -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsycl -triple spir64_gen -Werror=sycl-strict -DERROR -fsycl-is-device -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsycl -triple spir64 -Werror=sycl-strict -DERROR -fsycl-is-device -fsyntax-only -verify %s #include "Inputs/sycl.hpp" +class Foo; template __attribute__((sycl_kernel)) void kernel(F KernelFunc) { @@ -12,12 +11,10 @@ __attribute__((sycl_kernel)) void kernel(F KernelFunc) { template void parallel_for(F KernelFunc) { -#ifdef GPU - // expected-warning@+6 {{size of kernel arguments (7994 bytes) exceeds supported maximum of 2048 bytes on GPU}} -#elif ERROR - // expected-error@+4 {{size of kernel arguments (7994 bytes) exceeds supported maximum of 2048 bytes on GPU}} +#ifdef ERROR + // expected-error@+4 {{size of kernel arguments (7994 bytes) may exceed the supported maximum of 2048 bytes on some devices}} #else - // expected-no-diagnostics + // expected-warning@+2 {{size of kernel arguments (7994 bytes) may exceed the supported maximum of 2048 bytes on some devices}} #endif kernel(KernelFunc); } @@ -34,8 +31,6 @@ void use() { int Array[1991]; } Args; auto L = [=]() { (void)Args; }; -#if defined(GPU) || defined(ERROR) - // expected-note@+2 {{in instantiation of function template specialization 'parallel_for(L); + // expected-note@+1 {{in instantiation of function template specialization 'parallel_for(L); } diff --git a/clang/test/SemaSYCL/array-kernel-param.cpp b/clang/test/SemaSYCL/array-kernel-param.cpp index 945b7decd9f57..ea1d4ac4a899d 100644 --- a/clang/test/SemaSYCL/array-kernel-param.cpp +++ b/clang/test/SemaSYCL/array-kernel-param.cpp @@ -24,6 +24,8 @@ int main() { Accessor acc[2]; int a[2]; + int *a_ptrs[2]; + struct struct_acc_t { Accessor member_acc[2]; } struct_acc; @@ -32,17 +34,25 @@ int main() { struct foo_inner { int foo_inner_x; int foo_inner_y; - int foo_inner_z[2]; + int *foo_inner_z[2]; }; struct foo { int foo_a; foo_inner foo_b[2]; + int *foo_2D[2][1]; + int foo_c; + }; + + // Not decomposed. + struct foo2 { + int foo_a; int foo_2D[2][1]; int foo_c; }; foo struct_array[2]; + foo2 struct_array2[2]; int array_2D[2][3]; @@ -56,6 +66,11 @@ int main() { int local = a[1]; }); + a_kernel( + [=]() { + int local = *a_ptrs[1]; + }); + a_kernel( [=]() { struct_acc.member_acc[2].use(); @@ -75,6 +90,11 @@ int main() { [=]() { int local = array_2D[1][1]; }); + + a_kernel( + [=]() { + foo2 local = struct_array2[0]; + }); } // Check kernel_A parameters @@ -93,19 +113,40 @@ int main() { // CHECK-NEXT: MemberExpr {{.*}}__init // Check kernel_B parameters -// CHECK: FunctionDecl {{.*}}kernel_B{{.*}} 'void (int, int)' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'int' +// CHECK: FunctionDecl {{.*}}kernel_B{{.*}} 'void (__wrapper_class)' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ '__wrapper_class' // Check kernel_B inits // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl {{.*}} cinit // CHECK-NEXT: InitListExpr -// CHECK-NEXT: InitListExpr {{.*}} 'int [2]' -// CHECK: ImplicitCastExpr -// CHECK: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_' 'int' -// CHECK: ImplicitCastExpr -// CHECK: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_' 'int' +// CHECK-NEXT: ArrayInitLoopExpr {{.*}} 'int [2]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'int [2]' lvalue +// CHECK-NEXT: MemberExpr {{.*}} 'int [2]' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_' '__wrapper_class' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'int [2]' lvalue +// CHECK-NEXT: MemberExpr {{.*}} 'int [2]' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_' '__wrapper_class' + +// Check kernel_B_ptrs parameters +// CHECK: FunctionDecl {{.*}}kernel_B_ptrs{{.*}} 'void (__global int *, __global int *)' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ '__global int *' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ '__global int *' +// Check kernel_B_ptrs inits +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: DeclStmt +// CHECK-NEXT: VarDecl {{.*}} cinit +// CHECK-NEXT: InitListExpr +// CHECK-NEXT: InitListExpr {{.*}} 'int *[2]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: DeclRefExpr {{.*}} '__global int *' lvalue ParmVar {{.*}} '_arg_' '__global int *' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: DeclRefExpr {{.*}} '__global int *' lvalue ParmVar {{.*}} '_arg_' '__global int *' // Check kernel_C parameters // CHECK: FunctionDecl {{.*}}kernel_C{{.*}} 'void (__global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, __global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>)' @@ -133,30 +174,30 @@ int main() { // CHECK-NEXT: MemberExpr {{.*}}__init // Check kernel_D parameters -// CHECK: FunctionDecl {{.*}}kernel_D{{.*}} 'void (int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int)' +// CHECK: FunctionDecl {{.*}}kernel_D{{.*}} 'void (int, int, int, __wrapper_class, __wrapper_class, int, int, __wrapper_class, __wrapper_class, __wrapper_class, __wrapper_class, int, int, int, int, __wrapper_class, __wrapper_class, int, int, __wrapper_class, __wrapper_class, __wrapper_class, __wrapper_class, int)' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_a 'int' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_x 'int' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_y 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z '__wrapper_class' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z '__wrapper_class' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_x 'int' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_y 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_2D 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_2D 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z '__wrapper_class' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z '__wrapper_class' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_2D '__wrapper_class' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_2D '__wrapper_class' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_c 'int' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_a 'int' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_x 'int' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_y 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z '__wrapper_class' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z '__wrapper_class' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_x 'int' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_y 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_2D 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_2D 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z '__wrapper_class' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_inner_z '__wrapper_class' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_2D '__wrapper_class' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_2D '__wrapper_class' // CHECK-NEXT: ParmVarDecl {{.*}} used _arg_foo_c 'int' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt @@ -168,120 +209,164 @@ int main() { // Initializer for first element of struct_array // CHECK-NEXT: InitListExpr {{.*}} 'foo' -// CHECK-NEXT: ImplicitCastExpr +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_a' 'int' + // Initializer for struct array inside foo i.e. foo_inner foo_b[2] // CHECK-NEXT: InitListExpr {{.*}} 'foo_inner [2]' // Initializer for first element of inner struct array // CHECK-NEXT: InitListExpr {{.*}} 'foo_inner' -// CHECK-NEXT: ImplicitCastExpr +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_x' 'int' -// CHECK-NEXT: ImplicitCastExpr +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_y' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [2]' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[2]' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_z' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_inner_z' '__wrapper_class' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_z' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_inner_z' '__wrapper_class' // Initializer for second element of inner struct array // CHECK-NEXT: InitListExpr {{.*}} 'foo_inner' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_x' 'int' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_y' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [2]' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[2]' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_z' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_inner_z' '__wrapper_class' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_z' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [2][1]' -// CHECK-NEXT: InitListExpr {{.*}} 'int [1]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_inner_z' '__wrapper_class' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[2][1]' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[1]' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_2D' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [1]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_2D' '__wrapper_class' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[1]' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_2D' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_2D' '__wrapper_class' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_c' 'int' +// CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_c' 'int' // Initializer for second element of struct_array // CHECK-NEXT: InitListExpr {{.*}} 'foo' -// CHECK-NEXT: ImplicitCastExpr +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_a' 'int' + +// Initializer for struct array inside foo i.e. foo_inner foo_b[2] // CHECK-NEXT: InitListExpr {{.*}} 'foo_inner [2]' +// Initializer for first element of inner struct array // CHECK-NEXT: InitListExpr {{.*}} 'foo_inner' -// CHECK-NEXT: ImplicitCastExpr +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_x' 'int' -// CHECK-NEXT: ImplicitCastExpr +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_y' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [2]' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[2]' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_z' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_inner_z' '__wrapper_class' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_z' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_inner_z' '__wrapper_class' +// Initializer for second element of inner struct array // CHECK-NEXT: InitListExpr {{.*}} 'foo_inner' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_x' 'int' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_y' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [2]' -// CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_z' 'int' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[2]' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_inner_z' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [2][1]' -// CHECK-NEXT: InitListExpr {{.*}} 'int [1]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_inner_z' '__wrapper_class' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_2D' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [1]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_inner_z' '__wrapper_class' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[2][1]' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[1]' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_2D' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_2D' '__wrapper_class' +// CHECK-NEXT: InitListExpr {{.*}} 'int *[1]' // CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_foo_c' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_foo_2D' '__wrapper_class' // Check kernel_E parameters -// CHECK: FunctionDecl {{.*}}kernel_E{{.*}} 'void (int, int, int)' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_a 'int':'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_a 'int':'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_a 'int':'int' +// CHECK: FunctionDecl {{.*}}kernel_E{{.*}} 'void (S)' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'S':'S' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl {{.*}} used '(lambda at {{.*}}array-kernel-param.cpp{{.*}})' cinit // CHECK-NEXT: InitListExpr {{.*}} '(lambda at {{.*}}array-kernel-param.cpp{{.*}})' -// CHECK-NEXT: InitListExpr {{.*}} 'S' -// CHECK-NEXT: InitListExpr {{.*}} 'int [3]' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int':'int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'int':'int' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int':'int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'int':'int' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int':'int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'int':'int' +// CHECK-NEXT: CXXConstructExpr {{.*}} 'S':'S' 'void (const S &) noexcept' +// CHECK-NEXT: ImplicitCastExpr +// CHECK-NEXT: DeclRefExpr {{.*}} 'S':'S' lvalue ParmVar {{.*}} '_arg_' 'S':'S' // Check kernel_F parameters -// CHECK: FunctionDecl {{.*}}kernel_F{{.*}} 'void (int, int, int, int, int, int)' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'int' +// CHECK: FunctionDecl {{.*}}kernel_F{{.*}} 'void (__wrapper_class)' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ '__wrapper_class' // Check kernel_F inits // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl {{.*}} cinit // CHECK-NEXT: InitListExpr -// CHECK-NEXT: InitListExpr {{.*}} 'int [2][3]' -// CHECK-NEXT: InitListExpr {{.*}} 'int [3]' -// CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_' 'int' -// CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_' 'int' -// CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'int [3]' -// CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_' 'int' -// CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_' 'int' -// CHECK-NEXT: ImplicitCastExpr -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} '_arg_' 'int' +// CHECK-NEXT: ArrayInitLoopExpr {{.*}} 'int [2][3]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'int [2][3]' lvalue +// CHECK-NEXT: MemberExpr {{.*}} 'int [2][3]' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_' '__wrapper_class' +// CHECK-NEXT: ArrayInitLoopExpr {{.*}} 'int [3]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'int [3]' lvalue +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int [3]' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int (*)[3]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'int [2][3]' lvalue +// CHECK-NEXT: MemberExpr {{.*}} 'int [2][3]' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_' '__wrapper_class' +// CHECK-NEXT: ArrayInitIndexExpr {{.*}} 'unsigned long +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'int [3]' lvalue +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int [3]' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int (*)[3]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'int [2][3]' lvalue +// CHECK-NEXT: MemberExpr {{.*}} 'int [2][3]' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_' '__wrapper_class' +// CHECK-NEXT: ArrayInitIndexExpr {{.*}} 'unsigned long +// CHECK-NEXT: ArrayInitIndexExpr {{.*}} 'unsigned long + +// Check kernel_G parameters. +// CHECK: FunctionDecl {{.*}}kernel_G{{.*}} 'void (__wrapper_class)' +// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ '__wrapper_class' +// Check kernel_G inits +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: DeclStmt +// CHECK-NEXT: VarDecl {{.*}} cinit +// CHECK-NEXT: InitListExpr +// CHECK-NEXT: ArrayInitLoopExpr {{.*}} 'foo2 [2]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'foo2 [2]' lvalue +// CHECK-NEXT: MemberExpr {{.*}} 'foo2 [2]' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_' '__wrapper_class' +// CHECK-NEXT: CXXConstructExpr {{.*}} 'foo2' 'void (const foo2 &) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const foo2' lvalue +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'foo2' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'foo2 *' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'foo2 [2]' lvalue +// CHECK-NEXT: MemberExpr {{.*}} 'foo2 [2]' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} '__wrapper_class' lvalue ParmVar {{.*}} '_arg_' '__wrapper_class' +// CHECK-NEXT: ArrayInitIndexExpr {{.*}} 'unsigned long diff --git a/clang/test/SemaSYCL/basic-kernel-wrapper.cpp b/clang/test/SemaSYCL/basic-kernel-wrapper.cpp index 7fe3c8255153d..800b8ce030787 100644 --- a/clang/test/SemaSYCL/basic-kernel-wrapper.cpp +++ b/clang/test/SemaSYCL/basic-kernel-wrapper.cpp @@ -43,7 +43,7 @@ int main() { // CHECK: CXXMemberCallExpr {{.*}} 'void' // CHECK-NEXT: MemberExpr {{.*}} 'void ({{.*}}PtrType, range<1>, range<1>, id<1>)' lvalue .__init -// CHECK-NEXT: MemberExpr {{.*}} 'cl::sycl::accessor':'cl::sycl::accessor>' lvalue . +// CHECK-NEXT: MemberExpr {{.*}} 'cl::sycl::accessor':'cl::sycl::accessor>' lvalue . // CHECK-NEXT: DeclRefExpr {{.*}} '(lambda at {{.*}}basic-kernel-wrapper.cpp{{.*}})' lvalue Var // CHECK-NEXT: ImplicitCastExpr {{.*}} diff --git a/clang/test/SemaSYCL/buffer_location.cpp b/clang/test/SemaSYCL/buffer_location.cpp index 2d59fc819e1b0..ac3724d32ef0f 100644 --- a/clang/test/SemaSYCL/buffer_location.cpp +++ b/clang/test/SemaSYCL/buffer_location.cpp @@ -9,22 +9,24 @@ template class another_property_list { }; +template +using buffer_location = cl::sycl::INTEL::property::buffer_location::instance; + struct Base { int A, B; cl::sycl::accessor>> + cl::sycl::ONEAPI::accessor_property_list>> AccField; }; -struct Captured : Base, - cl::sycl::accessor>> { +struct Captured + : Base, + cl::sycl::accessor>> { int C; }; @@ -35,28 +37,28 @@ int main() { cl::sycl::accessor>> + cl::sycl::ONEAPI::accessor_property_list>> // CHECK: SYCLIntelBufferLocationAttr {{.*}} Implicit 2 accessorA; cl::sycl::accessor>> + cl::sycl::ONEAPI::accessor_property_list< + another_property, + buffer_location<3>>> // CHECK: SYCLIntelBufferLocationAttr {{.*}} Implicit 3 accessorB; cl::sycl::accessor> + cl::sycl::ONEAPI::accessor_property_list< + another_property>> accessorC; #else cl::sycl::accessor>> + cl::sycl::ONEAPI::accessor_property_list>> accessorD; cl::sycl::accessor, - cl::sycl::property::buffer_location<2>>> + cl::sycl::ONEAPI::accessor_property_list< + buffer_location<1>, + buffer_location<2>>> accessorF; #endif cl::sycl::kernel_single_task( @@ -82,7 +84,7 @@ int main() { #else //expected-error@+1{{buffer_location template parameter must be a non-negative integer}} accessorD.use(); - //expected-error@+1{{Fifth template parameter of the accessor must be of a property_list type}} + //expected-error@+1{{sixth template parameter of the accessor must be of accessor_property_list type}} accessorE.use(); //expected-error@+1{{Can't apply buffer_location property twice to the same accessor}} accessorF.use(); diff --git a/clang/test/SemaSYCL/decomposition.cpp b/clang/test/SemaSYCL/decomposition.cpp new file mode 100644 index 0000000000000..6830c944f239c --- /dev/null +++ b/clang/test/SemaSYCL/decomposition.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -fsycl -fsycl-is-device -ast-dump %s | FileCheck %s + +#include "Inputs/sycl.hpp" + +using namespace cl::sycl; + +struct has_acc { + accessor acc; +}; + +struct acc_base : accessor { + int i; +}; + +struct has_sampler { + sampler sampl; +}; + +struct has_spec_const { + ONEAPI::experimental::spec_constant SC; +}; + +handler H; + +struct has_stream { + stream s1{0, 0, H}; +}; + +struct has_half { + half h; +}; + +struct non_decomposed { + int i; + float f; + double d; +}; + +struct use_non_decomposed : non_decomposed { + non_decomposed member; + float f; + double d; +}; + +template +struct Test1 { + T a; + T b[2]; + non_decomposed d; + int i; +}; + +template +struct Test2 : T { + non_decomposed d; + int i; +}; + +template +__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) { + kernelFunc(); +} + +int main() { + + non_decomposed d; + non_decomposed ds[5]; + use_non_decomposed d2; + use_non_decomposed d2s[5]; + // Check to ensure that these are not decomposed. + kernel([=]() { return d.i + ds[0].i + d2.i + d2s[0].i; }); + // CHECK: FunctionDecl {{.*}}NonDecomp{{.*}} 'void (non_decomposed, __wrapper_class, use_non_decomposed, __wrapper_class)' + + { + Test1 t1; + kernel([=]() { return t1.i; }); + // CHECK: FunctionDecl {{.*}}Acc1{{.*}} 'void (__global char *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, __global char *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, __global char *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, non_decomposed, int)' + Test2 t2; + kernel([=]() { return t2.i; }); + // CHECK: FunctionDecl {{.*}}Acc2{{.*}} 'void (__global char *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, non_decomposed, int)' + Test1 t3; + kernel([=]() { return t3.i; }); + // CHECK: FunctionDecl {{.*}}Acc3{{.*}} 'void (__global char *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, int, __global char *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, int, __global char *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, int, non_decomposed, int)' + Test2 t4; + kernel([=]() { return t4.i; }); + // CHECK: FunctionDecl {{.*}}Acc4{{.*}} 'void (__global char *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, int, non_decomposed, int)' + } + + { + Test1 t1; + kernel([=]() { return t1.i; }); + // CHECK: FunctionDecl {{.*}}Sampl1{{.*}} 'void (sampler_t, sampler_t, sampler_t, non_decomposed, int)' + Test2 t2; + kernel([=]() { return t2.i; }); + // CHECK: FunctionDecl {{.*}}Sampl2{{.*}} 'void (sampler_t, non_decomposed, int)' + } + + { + Test1 t1; + kernel([=]() { return t1.i; }); + // CHECK: FunctionDecl {{.*}}SpecConst{{.*}} 'void (non_decomposed, int)' + Test2 t2; + kernel([=]() { return t2.i; }); + // CHECK: FunctionDecl {{.*}}SpecConst2{{.*}} 'void (non_decomposed, int)' + } + + { + Test1 t1; + kernel([=]() { return t1.i; }); + // CHECK: FunctionDecl {{.*}}Stream1{{.*}} 'void (cl::sycl::stream, __global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, cl::sycl::stream, __global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, cl::sycl::stream, __global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, non_decomposed, int)' + Test2 t2; + kernel([=]() { return t2.i; }); + // CHECK: FunctionDecl {{.*}}Stream2{{.*}} 'void (cl::sycl::stream, __global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, non_decomposed, int)' + } + + { + Test1 t1; + kernel([=]() { return t1.i; }); + // CHECK: FunctionDecl {{.*}}Half1{{.*}} 'void (cl::sycl::half, cl::sycl::half, cl::sycl::half, non_decomposed, int)' + Test2 t2; + kernel([=]() { return t2.i; }); + // CHECK: FunctionDecl {{.*}}Half2{{.*}} 'void (cl::sycl::half, non_decomposed, int)' + } +} diff --git a/clang/test/SemaSYCL/fake-accessors.cpp b/clang/test/SemaSYCL/fake-accessors.cpp index 3a7a44aa8dc68..d4dd2a0f60209 100644 --- a/clang/test/SemaSYCL/fake-accessors.cpp +++ b/clang/test/SemaSYCL/fake-accessors.cpp @@ -51,6 +51,6 @@ int main() { }); return 0; } -// CHECK: fake_accessors{{.*}} 'void (__global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, int, int) -// CHECK: accessor_typedef{{.*}} 'void (__global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, int, int) -// CHECK: accessor_alias{{.*}} 'void (__global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, int, int) +// CHECK: fake_accessors{{.*}} 'void (__global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, foo::cl::sycl::accessor, accessor) +// CHECK: accessor_typedef{{.*}} 'void (__global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, foo::cl::sycl::accessor, accessor) +// CHECK: accessor_alias{{.*}} 'void (__global int *, cl::sycl::range<1>, cl::sycl::range<1>, cl::sycl::id<1>, foo::cl::sycl::accessor, accessor) diff --git a/clang/test/SemaSYCL/implicit_kernel_type.cpp b/clang/test/SemaSYCL/implicit_kernel_type.cpp index defff13a989cf..4083c82987c72 100644 --- a/clang/test/SemaSYCL/implicit_kernel_type.cpp +++ b/clang/test/SemaSYCL/implicit_kernel_type.cpp @@ -51,10 +51,11 @@ class myWrapper2; int main() { queue q; #ifndef __SYCL_UNNAMED_LAMBDA__ - // expected-note@+1 {{InvalidKernelName1 declared here}} + // expected-note@+3 {{InvalidKernelName1 declared here}} + // expected-note@+4{{in instantiation of function template specialization}} + // expected-error@28 {{kernel needs to have a globally-visible name}} class InvalidKernelName1 {}; q.submit([&](handler &h) { - // expected-error@+1 {{kernel needs to have a globally-visible name}} h.single_task([]() {}); }); #endif diff --git a/clang/test/SemaSYCL/inheritance.cpp b/clang/test/SemaSYCL/inheritance.cpp index f8dcfaf84af94..ab1f505619fee 100644 --- a/clang/test/SemaSYCL/inheritance.cpp +++ b/clang/test/SemaSYCL/inheritance.cpp @@ -4,7 +4,7 @@ class second_base { public: - int e; + int *e; }; class InnerFieldBase { @@ -40,13 +40,11 @@ int main() { } // Check declaration of the kernel -// CHECK: derived{{.*}} 'void (int, int, int, int, int)' +// CHECK: derived{{.*}} 'void (base, __wrapper_class, int) // Check parameters of the kernel -// CHECK: ParmVarDecl {{.*}} used _arg_b 'int' -// CHECK: ParmVarDecl {{.*}} used _arg_d 'int' -// CHECK: ParmVarDecl {{.*}} used _arg_c 'int' -// CHECK: ParmVarDecl {{.*}} used _arg_e 'int' +// CHECK: ParmVarDecl {{.*}} used _arg__base 'base' +// CHECK: ParmVarDecl {{.*}} used _arg_e '__wrapper_class' // CHECK: ParmVarDecl {{.*}} used _arg_a 'int' // Check initializers for derived and base classes. @@ -54,17 +52,13 @@ int main() { // Base classes should be initialized first. // CHECK: VarDecl {{.*}} derived 'derived' cinit // CHECK-NEXT: InitListExpr {{.*}} 'derived' -// CHECK-NEXT: InitListExpr {{.*}} 'base' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' -// CHECK-NEXT: DeclRefExpr {{.*}} lvalue ParmVar {{.*}} '_arg_b' 'int' -// CHECK-NEXT: InitListExpr {{.*}} 'InnerField' -// CHECK-NEXT: InitListExpr {{.*}} 'InnerFieldBase' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' -// CHECK-NEXT: DeclRefExpr {{.*}} lvalue ParmVar {{.*}} '_arg_d' 'int' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' -// CHECK-NEXT: DeclRefExpr {{.*}} lvalue ParmVar {{.*}} '_arg_c' 'int' +// CHECK-NEXT: CXXConstructExpr {{.*}} 'base' 'void (const base &) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const base' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} lvalue ParmVar {{.*}} '_arg__base' 'base' // CHECK-NEXT: InitListExpr {{.*}} 'second_base' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' -// CHECK-NEXT: DeclRefExpr {{.*}} lvalue ParmVar {{.*}} '_arg_e' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: ImplicitCastExpr {{.*}} '__global int *' +// CHECK-NEXT: MemberExpr {{.*}} '__global int *' lvalue . +// CHECK-NEXT: DeclRefExpr {{.*}} lvalue ParmVar {{.*}} '_arg_e' '__wrapper_class' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' // CHECK-NEXT: DeclRefExpr {{.*}} lvalue ParmVar {{.*}} '_arg_a' 'int' diff --git a/clang/test/SemaSYCL/kernelname-enum.cpp b/clang/test/SemaSYCL/kernelname-enum.cpp index 07c50b35f519d..d49f654b34c41 100644 --- a/clang/test/SemaSYCL/kernelname-enum.cpp +++ b/clang/test/SemaSYCL/kernelname-enum.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-int-header=%t.h -fsyntax-only -Wno-sycl-2017-compat -verify %s +// expected-error@Inputs/sycl.hpp:220 2{{kernel name is invalid. Unscoped enum requires fixed underlying type}} #include "Inputs/sycl.hpp" enum unscoped_enum_int : int { @@ -7,7 +8,7 @@ enum unscoped_enum_int : int { val_2 }; -// expected-note@+1 {{'unscoped_enum_no_type_set' declared here}} +// expected-note@+1 2 {{'unscoped_enum_no_type_set' declared here}} enum unscoped_enum_no_type_set { val_3, val_4 @@ -29,13 +30,18 @@ class dummy_functor_1 { void operator()() const {} }; -// expected-error@+2 {{kernel name is invalid. Unscoped enum requires fixed underlying type}} template class dummy_functor_2 { public: void operator()() const {} }; +template