diff --git a/.ci/green-dragon/lldb-windows.groovy b/.ci/green-dragon/lldb-windows.groovy index 569932fb0ff92..bec44d39f8961 100644 --- a/.ci/green-dragon/lldb-windows.groovy +++ b/.ci/green-dragon/lldb-windows.groovy @@ -48,7 +48,7 @@ pipeline { } } - stage('Build and Test (No LLDB Server)') { + stage('Build and Test') { steps { timeout(60) { catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { @@ -81,28 +81,6 @@ cmake -G Ninja ^ -DLLVM_LIT_ARGS="-v --time-tests --xunit-xml-output=C:\\workspace\\llvm-build\\test\\results-no-lldb-server.xml" ^ -DPython3_EXECUTABLE="C:\\Program Files\\Python313\\python.exe" || exit /b 1 ninja check-lldb -C ..\\llvm-build || exit /b 1 -''' - bat ''' - docker run --rm ^ - -e BUILD_TYPE=%BUILD_TYPE% ^ - -v "%CD%:C:\\workspace" ^ - -w "C:\\workspace\\llvm-project" ^ - swiftlang/swift-ci:lldb-windowsservercore-1809 ^ - cmd /C C:\\workspace\\build.bat - ''' - } - } - } - } - - stage('Test (LLDB Server)') { - steps { - timeout(30) { - catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { - writeFile file: 'test-lldb-server.bat', text: '''@echo off -call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat" || exit /b 1 - -set "PATH=%PATH%;C:\\Program Files\\Git\\usr\\bin" cmake -G Ninja ^ -S llvm ^ @@ -117,12 +95,13 @@ ninja check-lldb -C ..\\llvm-build || exit /b 1 -v "%CD%:C:\\workspace" ^ -w "C:\\workspace\\llvm-project" ^ swiftlang/swift-ci:lldb-windowsservercore-1809 ^ - cmd /C C:\\workspace\\test-lldb-server.bat + cmd /C C:\\workspace\\build.bat ''' } } } } + } post { always { diff --git a/bolt/test/AArch64/got-load-symbolization.s b/bolt/test/AArch64/got-load-symbolization.s index b4d6826887580..399859fd7bfd5 100644 --- a/bolt/test/AArch64/got-load-symbolization.s +++ b/bolt/test/AArch64/got-load-symbolization.s @@ -38,9 +38,9 @@ _start: # CHECK-NEXT: adrp x2, __BOLT_got_zero # CHECK-NEXT: nop # CHECK-NEXT: ldr x2, [x2, :lo12:__BOLT_got_zero{{.*}}] - adrp x2, :got:near + adrp x2, :got:near2 nop - ldr x2, [x2, :got_lo12:near] + ldr x2, [x2, :got_lo12:near2] ## Load data object with local visibility. Relaxable into adrp+add. # CHECK-NEXT: adrp x3, "local_far_data/1" @@ -58,6 +58,7 @@ _start: .size _start, .-_start .weak near +.weak near2 .weak far .weak far_data @@ -77,6 +78,12 @@ near: ret .size near, .-near + .globl near2 + .type near2, @function +near2: + ret +.size near2, .-near2 + #--- far.s .text diff --git a/bolt/test/AArch64/lite-mode.s b/bolt/test/AArch64/lite-mode.s index f2d06219f7a2d..24c31772b8475 100644 --- a/bolt/test/AArch64/lite-mode.s +++ b/bolt/test/AArch64/lite-mode.s @@ -24,12 +24,12 @@ # CHECK-COMPACT-NOT: <_start.org.0> ## Verify that the number of FDEs matches the number of functions in the output -## binary. There are three original functions and two optimized. +## binary. There are four original functions and three optimized. ## NOTE: at the moment we are emitting extra FDEs for patched functions, thus ## there is one more FDE for _start. # RUN: llvm-readelf -u %t.bolt | grep -wc FDE \ # RUN: | FileCheck --check-prefix=CHECK-FDE %s -# CHECK-FDE: 6 +# CHECK-FDE: 8 ## In lite mode, optimized code will be separated from the original .text by ## over 128MB, making it impossible for call/bl instructions in cold functions @@ -106,9 +106,9 @@ cold_function: # CHECK-NEXT: add x4 ## Check that non-relaxable GOT load is left intact. - adrp x5, :got:far_func + adrp x5, :got:far_func2 nop - ldr x5, [x5, #:got_lo12:far_func] + ldr x5, [x5, #:got_lo12:far_func2] # CHECK-INPUT-NEXT: adrp x5 # CHECK-INPUT-NEXT: nop # CHECK-INPUT-NEXT: ldr x5 @@ -155,3 +155,12 @@ far_func: ret x30 .cfi_endproc .size far_func, .-far_func + + .globl far_func2 + .type far_func2, %function +far_func2: +# FDATA: 0 [unknown] 0 1 far_func2 0 0 100 + .cfi_startproc + ret x30 + .cfi_endproc + .size far_func2, .-far_func2 diff --git a/bolt/test/AArch64/use-old-text-zero-padding.c b/bolt/test/AArch64/use-old-text-zero-padding.c index 3c80c906eee36..3cd429fb2c24c 100644 --- a/bolt/test/AArch64/use-old-text-zero-padding.c +++ b/bolt/test/AArch64/use-old-text-zero-padding.c @@ -25,7 +25,7 @@ // RUN: llvm-readelf -S %t/test.bolt | awk '$3==".text"{print $6, $7}' \ // RUN: > %t/txt-loc // RUN: bash -c "read O S < %t/txt-loc; \ -// RUN: od -A x -t x1 -N 0x20 -j \$((0x\$O + 0x\$S)) %t/test.bolt" \ +// RUN: od -A x -t x1 -N 32 -j \$((0x\$O + 0x\$S)) %t/test.bolt" \ // RUN: | FileCheck %s --check-prefix=PADDING // PADDING: {{[0-9a-f]+}} 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.cpp b/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.cpp index 5b5fe4c48724b..d77163009358b 100644 --- a/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.cpp @@ -12,12 +12,24 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { +TrivialSwitchCheck::TrivialSwitchCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreMacros(Options.get("IgnoreMacros", true)) {} + +void TrivialSwitchCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreMacros", IgnoreMacros); +} + void TrivialSwitchCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(switchStmt().bind("switch"), this); } void TrivialSwitchCheck::check(const MatchFinder::MatchResult &Result) { const auto *Switch = Result.Nodes.getNodeAs("switch"); + if (IgnoreMacros && Switch->getBeginLoc().isMacroID()) + return; + std::size_t CaseCount = 0; bool HasDefault = false; diff --git a/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.h b/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.h index 9eff86475932d..28afb74500332 100644 --- a/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.h +++ b/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.h @@ -19,13 +19,16 @@ namespace clang::tidy::readability { /// https://clang.llvm.org/extra/clang-tidy/checks/readability/trivial-switch.html class TrivialSwitchCheck : public ClangTidyCheck { public: - TrivialSwitchCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + TrivialSwitchCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; std::optional getCheckTraversalKind() const override { return TK_IgnoreUnlessSpelledInSource; } + +private: + const bool IgnoreMacros; }; } // namespace clang::tidy::readability diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 082cc5cb78bc0..5abcc053652ee 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -910,6 +910,11 @@ Changes in existing checks ` check by avoiding a crash from invalid ``Abbreviations`` option. +- Improved :doc:`readability-trivial-switch + ` check by adding an + `IgnoreMacros` option. When enabled, the check will ignore switch + statements originating from macros. + - Improved :doc:`readability-use-anyofallof ` check by emitting a diagnostic note to suggest materializing the temporary range when iterating over temporary diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/trivial-switch.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/trivial-switch.rst index efcee2f0c7caf..dfed2576ffa81 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/trivial-switch.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/trivial-switch.rst @@ -34,3 +34,11 @@ Otherwise, the ``switch`` can be better expressed with an ``if`` statement. // The switch without any labels will be diagnosed. int i = 42; switch (i) {} + +Options +------- + +.. option:: IgnoreMacros + + If set to `true`, the check will not give warnings inside macros. Default + is `true`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/trivial-switch.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/trivial-switch.cpp index bc693df6599c4..b01f0d8462f3b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/trivial-switch.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/trivial-switch.cpp @@ -1,4 +1,7 @@ // RUN: %check_clang_tidy -std=c++98-or-later %s readability-trivial-switch %t +// RUN: %check_clang_tidy -std=c++98-or-later -check-suffixes=,MACROS %s \ +// RUN: readability-trivial-switch %t -- \ +// RUN: -config="{CheckOptions: {readability-trivial-switch.IgnoreMacros: false}}" void bad(int I) { switch (I) { @@ -42,3 +45,14 @@ void good(int I) { break; } } + +#define SINGLE_CASE_SWITCH(I) \ + switch (I) { \ + case 0: \ + break; \ + } + +void macro(int I) { + SINGLE_CASE_SWITCH(I) + // CHECK-MESSAGES-MACROS: :[[@LINE-1]]:3: warning: switch with only one case; use an if statement +} diff --git a/clang/cmake/modules/ClangConfig.cmake.in b/clang/cmake/modules/ClangConfig.cmake.in index e199c7e17b6b7..68f723d050117 100644 --- a/clang/cmake/modules/ClangConfig.cmake.in +++ b/clang/cmake/modules/ClangConfig.cmake.in @@ -13,10 +13,7 @@ set(CLANG_LINK_CLANG_DYLIB "@CLANG_LINK_CLANG_DYLIB@") set(CLANG_DEFAULT_LINKER "@CLANG_DEFAULT_LINKER@") # Provide all our library targets to users. -# Skip when cross-compiling, as host library targets are not usable. -if(NOT CMAKE_CROSSCOMPILING) - @CLANG_CONFIG_INCLUDE_EXPORTS@ -endif() +@CLANG_CONFIG_INCLUDE_EXPORTS@ # By creating clang-tablegen-targets here, subprojects that depend on Clang's # tablegen-generated headers can always depend on this target whether building diff --git a/clang/docs/AMDGPUSupport.rst b/clang/docs/AMDGPUSupport.rst index 18e3de8abe92a..8ca537fa5d729 100644 --- a/clang/docs/AMDGPUSupport.rst +++ b/clang/docs/AMDGPUSupport.rst @@ -57,3 +57,10 @@ Predefined Macros - Defined if FP64 instruction is available (deprecated). Please note that the specific architecture and feature names will vary depending on the GPU. Also, some macros are deprecated and may be removed in future releases. + + +Target-Specific Builtins +======================== + +Clang exposes AMDGPU hardware intrinsics as target-specific builtins with the +``__builtin_amdgcn_`` prefix. These are documented in :doc:`AMDGPUBuiltinReference`. diff --git a/clang/docs/LanguageExtensions.md b/clang/docs/LanguageExtensions.md index 68416e801bd5d..c0b921d058777 100644 --- a/clang/docs/LanguageExtensions.md +++ b/clang/docs/LanguageExtensions.md @@ -5538,6 +5538,40 @@ int a = 1; __builtin_dcbf (&a); ``` +### z/OS Language Extensions + +#### z/OS builtins + +z/OS supports builtins for compare-and-swap operations that generate the +corresponding z/OS assembly instructions (CS, CSG, CDSG). These builtins compare +the value pointed to by oldptr to the value pointed to by curptr. If they are +equal, the value pointed to by newword (or newword itself for `__cs`) is +copied into the location pointed to by curptr. If they are unequal, the value +pointed to by curptr is copied into the location pointed to by oldptr. +The builtins return 0 if the values are equal, or 1 if they are unequal. + +- `int __cs(unsigned int *oldptr, unsigned int *curptr, unsigned int newword)` + + Generates a 4-byte compare-and-swap using the CS instruction. + Use `__cs` instead of `__cs1` when the newword arg is an r-value instead + of an l-value. + +- `int __cs1(void *oldptr, void *curptr, void *newword)` + + Generates a 4-byte compare-and-swap using the CS instruction. + +- `int __csg(void *oldptr, void *curptr, void *newword)` + + Generates an 8-byte compare-and-swap using the CSG instruction. + +- `int __cds1(void *oldptr, void *curptr, void *newword)` + + Generates an 8-byte compare-and-swap using the CSG instruction. + +- `int __cdsg(void *oldptr, void *curptr, void *newword)` + + Generates a 16-byte compare-and-swap using the CDSG instruction. + ## Extensions for Static Analysis Clang supports additional attributes that are useful for documenting program diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 696aed167e621..449a3792eb4ba 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -799,6 +799,10 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the - Fixed an assertion where we improperly handled implicit conversions to integral types from an atomic-type with a conversion function. (#GH201770) - Fixed assertion failures involving code completion with delayed default arguments and exception specifications. (#GH200879) - Fixed a regression where calling a function that takes a class-type parameter by value inside `decltype` of a concept could be incorrectly rejected when used as a non-type template argument. (#GH175831) +- Clang no longer crashes if `__attribute__((cleanup))` is applied to an invalid declaration. Furthermore, in declarations that + contain multiple `cleanup` attributes, Clang now only uses the last one, matching GCC's behaviour (previously, Clang + would only use the first one). A new warning that diagnoses such declarations has been added to `-Wignored-attributes`. + (#GH191829) - Fixed a crash in the constant evaluator when an ill-formed array new-expression whose bound could not be determined (e.g. `new int[]()`) was used in a constant expression. (#GH200139) - Clang now defines the GCC-compatible predefined macros `__WCHAR_MIN__`, `__WINT_MIN__`, and `__SIG_ATOMIC_MIN__`. (#GH199678) @@ -846,6 +850,7 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the - Clang no longer errors on overloads with different ref-qualifiers and constraints. (#GH120812) - Fixed a crash when a default argument is passed to an explicit object parameter. (#GH176639) - Fixed an alias template CTAD crash. +- Improvements to typo correction involving template names. (#GH207498) - Correctly diagnose uses of `co_await` / `co_yield` in the default argument of nested function declarations. (#GH98923) - Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741) - Clang incorrectly instantiated variable specializations outside of the immediate context. (#GH54439) @@ -942,6 +947,7 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the immediate-escalated callable. (#GH192846) - Fixed a crash when passing one sized implicitly casted vector to a `abs` function. (#GH204777) - Fixed a crash when diagnosing an invalid out-of-line definition of a member class template. (#GH201490) +- Fixed a crash in the parser when a missing semicolon after a tag definition is followed by a template-id not preceded by `::`. (#GH207992) ### OpenACC Specific Changes diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 062c8b0469223..92766d843d4b1 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -3967,6 +3967,23 @@ The goal of this rule is to make sure that lifetime of any dynamically allocated The rules of when to use and not to use CheckedPtr / CheckedRef are same as alpha.webkit.UncountedCallArgsChecker for ref-counted objects. +alpha.webkit.UncheckedLambdaCapturesChecker +""""""""""""""""""""""""""""""""""""""""""" +Raw pointers and references to unchecked types can't be captured in lambdas. Only CheckedPtr or CheckedRef is allowed. + +.. code-block:: cpp + + struct CheckedObject { + void incrementCheckedPtr() {} + void decrementCheckedPtr() {} + }; + + void foo(CheckedObject* a, CheckedObject& b) { + [&, a](){ // warn about 'a' + do_something(b); // warn about 'b' + }; + }; + alpha.webkit.UnretainedCallArgsChecker """""""""""""""""""""""""""""""""""""" The goal of this rule is to make sure that lifetime of any dynamically allocated NS or CF objects passed as a call argument keeps its memory region past the end of the call. This applies to call to any function, method, lambda, function pointer or functor. NS or CF objects aren't supposed to be allocated on stack so we check arguments for parameters of raw pointers and references to unretained types. diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 88c900203630a..a6e9b3bcaa608 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2049,13 +2049,17 @@ class FunctionDecl : public DeclaratorDecl, }; - /// Stashed information about a defaulted/deleted function body. + /// Stashed information about a defaulted/deleted function body, including + /// the active FP pragma overrides (FPOptionsOverride) from the declaration + /// site. These overrides are required to correctly synthesize the function + /// body. class DefaultedOrDeletedFunctionInfo final : llvm::TrailingObjects { friend TrailingObjects; unsigned NumLookups; bool HasDeletedMessage; + FPOptionsOverride FPFeatures; size_t numTrailingObjects(OverloadToken) const { return NumLookups; @@ -2064,8 +2068,11 @@ class FunctionDecl : public DeclaratorDecl, public: static DefaultedOrDeletedFunctionInfo * Create(ASTContext &Context, ArrayRef Lookups, + FPOptionsOverride FPFeatures, StringLiteral *DeletedMessage = nullptr); + FPOptionsOverride getFPFeatures() const { return FPFeatures; } + /// Get the unqualified lookup results that should be used in this /// defaulted function definition. ArrayRef getUnqualifiedLookups() const { diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.td b/clang/include/clang/Basic/BuiltinsAMDGPU.td index 306af993fd869..8c64116066971 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.td +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.td @@ -242,6 +242,10 @@ def __builtin_amdgcn_qsad_pk_u16_u8 : AMDGPUBuiltin<"uint64_t(uint64_t, unsigned def __builtin_amdgcn_mqsad_pk_u16_u8 : AMDGPUBuiltin<"uint64_t(uint64_t, unsigned int, uint64_t)", [Const], "mqsad-pk-insts">; def __builtin_amdgcn_mqsad_u32_u8 : AMDGPUBuiltin<"_ExtVector<4, unsigned int>(uint64_t, unsigned int, _ExtVector<4, unsigned int>)", [Const], "mqsad-insts">; +//===----------------------------------------------------------------------===// +// Buffer builtins. +//===----------------------------------------------------------------------===// + def __builtin_amdgcn_make_buffer_rsrc : AMDGPUBuiltin<"__amdgpu_buffer_rsrc_t(void *, short, int64_t, int)", [Const]>; def __builtin_amdgcn_raw_buffer_store_b8 : AMDGPUBuiltin<"void(unsigned char, __amdgpu_buffer_rsrc_t, int, int, _Constant int)">; def __builtin_amdgcn_raw_buffer_store_b16 : AMDGPUBuiltin<"void(unsigned short, __amdgpu_buffer_rsrc_t, int, int, _Constant int)">; @@ -280,6 +284,32 @@ def __builtin_amdgcn_raw_ptr_buffer_load_async_lds : AMDGPUBuiltin<"void(__amdgp def __builtin_amdgcn_struct_ptr_buffer_load_lds : AMDGPUBuiltin<"void(__amdgpu_buffer_rsrc_t, void address_space<3> *, _Constant unsigned int, int, int, int, _Constant int, _Constant int)", [], "vmem-to-lds-load-insts">; def __builtin_amdgcn_struct_ptr_buffer_load_async_lds : AMDGPUBuiltin<"void(__amdgpu_buffer_rsrc_t, void address_space<3> *, _Constant unsigned int, int, int, int, _Constant int, _Constant int)", [], "vmem-to-lds-load-insts">; +let Documentation = [DocSBufferLoad], ArgNames = ["rsrc", "offset", "aux"] in { +def __builtin_amdgcn_s_buffer_load_i32 : AMDGPUBuiltin<"int(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v2i32 : AMDGPUBuiltin<"_Vector<2, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v3i32 : AMDGPUBuiltin<"_Vector<3, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v4i32 : AMDGPUBuiltin<"_Vector<4, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v8i32 : AMDGPUBuiltin<"_Vector<8, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v16i32 : AMDGPUBuiltin<"_Vector<16, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_f32 : AMDGPUBuiltin<"float(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v2f32 : AMDGPUBuiltin<"_Vector<2, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v3f32 : AMDGPUBuiltin<"_Vector<3, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v4f32 : AMDGPUBuiltin<"_Vector<4, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v8f32 : AMDGPUBuiltin<"_Vector<8, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v16f32 : AMDGPUBuiltin<"_Vector<16, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_i8 : AMDGPUBuiltin<"char(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_u8 : AMDGPUBuiltin<"unsigned char(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_i16 : AMDGPUBuiltin<"short(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_u16 : AMDGPUBuiltin<"unsigned short(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v2i8 : AMDGPUBuiltin<"_Vector<2, char>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v3i8 : AMDGPUBuiltin<"_Vector<3, char>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v4i8 : AMDGPUBuiltin<"_Vector<4, char>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_f16 : AMDGPUBuiltin<"_Float16(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v2f16 : AMDGPUBuiltin<"_Vector<2, _Float16>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v3f16 : AMDGPUBuiltin<"_Vector<3, _Float16>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v4f16 : AMDGPUBuiltin<"_Vector<4, _Float16>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +} + //===----------------------------------------------------------------------===// // Global Available/Visible memory accesses. //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Basic/BuiltinsAMDGPUDocs.td b/clang/include/clang/Basic/BuiltinsAMDGPUDocs.td index c8a1b5a824f53..c78c8ec291eef 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPUDocs.td +++ b/clang/include/clang/Basic/BuiltinsAMDGPUDocs.td @@ -711,3 +711,54 @@ of the output. The operand must be uniform across the wavefront. A divergent value gives an undefined result. }]; } + +//===----------------------------------------------------------------------===// +// S-Buffer Load Builtins +//===----------------------------------------------------------------------===// + +def DocCatSBufferLoad : DocumentationCategory<"S-Buffer Load Builtins"> { + let Content = [{ +These builtins lower to ``llvm.amdgcn.s.buffer.load`` and issue an +``s_buffer_load`` when the byte offset is uniform across the wavefront. +When the offset is divergent, the backend may lower to a ``buffer_load``. + +.. warning:: + + These builtins should generally be avoided. They must only be used to emit + ``s_buffer_load`` instructions that access memory not modified during kernel + execution. ``s_buffer_load`` uses a separate cache that is not coherent with + the caches used by other load and store operations. The compiler does not + verify the alignment requirements imposed by ``s_buffer_load``. However, + because automatic promotion of ``buffer_load`` to ``s_buffer_load`` where + legal is not yet fully implemented, these builtins are provided so that + programmers can use such load operations directly. + +These builtins take the buffer resource as ``__amdgpu_buffer_rsrc_t``, which +can be created with ``__builtin_amdgcn_make_buffer_rsrc``. The backend +lowers the resource to the 4-dword SGPR descriptor required by +``llvm.amdgcn.s.buffer.load``. + +The return type selects the load width. Separate builtins are provided for +each supported scalar and vector element type. +}]; +} + +def DocSBufferLoad : Documentation { + let Category = DocCatSBufferLoad; + let Content = [{ +Loads data from a buffer using an SGPR buffer descriptor. + +- ``rsrc``: buffer resource descriptor. +- ``offset``: byte offset from the base of the buffer. May be variable; a + uniform offset enables ``s_buffer_load`` selection. +- ``aux``: cache-policy and control flags. Must be a compile-time constant. + The encoding is target-dependent. Common fields include: + + - Pre-GFX12: bit 0 = glc, bit 1 = slc, bit 2 = dlc (GFX10/GFX11), bit 3 = + swz, bit 4 = scc (GFX90a). + - GFX942: bit 0 = sc0, bit 1 = nt, bit 3 = swz, bit 4 = sc1. + - GFX12+: bits [0-2] = th, bits [3-4] = scope, bit 6 = swz. + + The volatile bit is not permitted for this intrinsic. +}]; +} diff --git a/clang/include/clang/Basic/BuiltinsZOS.td b/clang/include/clang/Basic/BuiltinsZOS.td new file mode 100644 index 0000000000000..2089518fd18a8 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsZOS.td @@ -0,0 +1,27 @@ +//===-- BuiltinsZOS.td - z/OS Builtin function 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 z/OS-specific builtin function database. +// +//===----------------------------------------------------------------------===// + +include "clang/Basic/BuiltinsBase.td" + +class SystemZNoPrefixBuiltin : Builtin { + let Spellings = [NAME]; + let Prototype = prototype; +} + +// compare and swap functions +let Attributes = [NoThrow] in { + def __cs : SystemZNoPrefixBuiltin<"int(unsigned int *, unsigned int *, unsigned int)">; + def __cs1 : SystemZNoPrefixBuiltin<"int(void *, void *, void *)">; + def __csg : SystemZNoPrefixBuiltin<"int(void *, void *, void *)">; + def __cds1 : SystemZNoPrefixBuiltin<"int(void *, void *, void *)">; + def __cdsg : SystemZNoPrefixBuiltin<"int(void *, void *, void *)">; +} diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index d90d326027583..d334c1d41e475 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -146,6 +146,10 @@ clang_tablegen(BuiltinsX86_64.inc -gen-clang-builtins SOURCE BuiltinsX86_64.td TARGET ClangBuiltinsX86_64) +clang_tablegen(BuiltinsZOS.inc -gen-clang-builtins + SOURCE BuiltinsZOS.td + TARGET ClangBuiltinsZOS) + clang_tablegen(BuiltinTemplates.inc -gen-clang-builtin-templates SOURCE BuiltinTemplates.td TARGET ClangBuiltinTemplates) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fde890f43e134..9414b022992ea 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4866,6 +4866,9 @@ def err_attribute_cleanup_func_must_take_one_arg : Error< def err_attribute_cleanup_func_arg_incompatible_type : Error< "'cleanup' function %0 parameter has " "%diff{type $ which is incompatible with type $|incompatible type}1,2">; +def warn_duplicate_cleanup_attr : Warning< + "declaration has multiple 'cleanup' attributes; all but the last one will be ignored">, + InGroup; def err_attribute_malloc_arg_not_function : Error< "'malloc' argument %select{for deallocator |%1 |%1 }0is not a %select{||single }0function">; def err_attribute_malloc_arg_not_function_with_pointer_arg : Error< @@ -13832,6 +13835,8 @@ def note_hlsl_resource_range_here: Note<"overlapping resource range here">; def err_hlsl_incomplete_resource_array_in_function_param: Error< "incomplete resource array in a function parameter">; +def err_hlsl_resource_param_in_noinline_function: Error< + "resource type %0 cannot be used as a parameter of a noinline function">; def err_hlsl_assign_to_global_resource: Error< "assignment to global resource variable %0 is not allowed">; def warn_hlsl_assigning_local_resource_is_not_unique diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 6c86300fc5581..f21131622d03d 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -989,6 +989,10 @@ class FPOptions { /// /// The is implemented as a value of the new FPOptions plus a mask showing which /// fields are actually set in it. +/// +/// NOTE: This type is serialized into the AST format (e.g. for defaulted +/// functions). When adding a new field here or in FPOptions, ensure that the +/// AST VERSION_MAJOR is bumped if it changes the layout or size. class FPOptionsOverride { FPOptions Options = FPOptions::getFromOpaqueInt(0); FPOptions::storage_type OverrideMask = 0; diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 8cf8720f74573..5828aae483026 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -457,13 +457,18 @@ namespace clang { /// SystemZ builtins namespace SystemZ { - enum { - LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, #define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsSystemZ.inc" #undef GET_BUILTIN_ENUMERATORS - LastTSBuiltin - }; + FirstZOSBuiltin, + LastSystemZBuiltin = FirstZOSBuiltin - 1, +#define GET_BUILTIN_ENUMERATORS +#include "clang/Basic/BuiltinsZOS.inc" +#undef GET_BUILTIN_ENUMERATORS + LastTSBuiltin + }; } /// WebAssembly builtins diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index b58434bef014f..5ffed6deccffe 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -7227,6 +7227,8 @@ def mavx512bf16 : Flag<["-"], "mavx512bf16">, Group; def mno_avx512bf16 : Flag<["-"], "mno-avx512bf16">, Group; def mavx512bitalg : Flag<["-"], "mavx512bitalg">, Group; def mno_avx512bitalg : Flag<["-"], "mno-avx512bitalg">, Group; +def mavx512bmm : Flag<["-"], "mavx512bmm">, Group; +def mno_avx512bmm : Flag<["-"], "mno-avx512bmm">, Group; def mavx512bw : Flag<["-"], "mavx512bw">, Group; def mno_avx512bw : Flag<["-"], "mno-avx512bw">, Group; def mavx512cd : Flag<["-"], "mavx512cd">, Group; diff --git a/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h b/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h new file mode 100644 index 0000000000000..30b50d3c28fb2 --- /dev/null +++ b/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h @@ -0,0 +1,50 @@ +//===- SARIFTransformationReportFormat.h ------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// Built-in SARIF 2.1.0 transformation-report writer. Drives clang's existing +// `SarifDocumentWriter`; emits no `fix` keys (source edits live in the +// separate edit file). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_SOURCETRANSFORMATION_SARIFTRANSFORMATIONREPORTFORMAT_H +#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_SOURCETRANSFORMATION_SARIFTRANSFORMATIONREPORTFORMAT_H + +#include "clang/Basic/Sarif.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace clang { +class SourceManager; +} // namespace clang + +namespace clang::ssaf { + +struct ReportResult { + std::string RuleId; + clang::SarifResultLevel Level; + clang::CharSourceRange Range; + std::string Message; +}; + +struct ReportDocument { + std::string TransformationName; + const clang::SourceManager &SM; + std::vector Results; +}; + +/// Writes \p Doc to \p Path as a SARIF JSON document. +llvm::Error writeSARIFTransformationReport(const ReportDocument &Doc, + llvm::StringRef Path); + +} // namespace clang::ssaf + +#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_SOURCETRANSFORMATION_SARIFTRANSFORMATIONREPORTFORMAT_H diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 279380de2f7fe..73388948b5750 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -44,7 +44,7 @@ namespace serialization { /// Version 4 of AST files also requires that the version control branch and /// revision match exactly, since there is no backward compatibility of /// AST files at this time. -const unsigned VERSION_MAJOR = 38; +const unsigned VERSION_MAJOR = 39; /// AST file minor version number supported by this version of /// Clang. diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index d33b21245bd7f..949e20d1fb98d 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1773,6 +1773,10 @@ def UncountedLocalVarsChecker : Checker<"UncountedLocalVarsChecker">, HelpText<"Check uncounted local variables.">, Documentation; +def UncheckedLambdaCapturesChecker : Checker<"UncheckedLambdaCapturesChecker">, + HelpText<"Check unchecked lambda captures.">, + Documentation; + def UncheckedLocalVarsChecker : Checker<"UncheckedLocalVarsChecker">, HelpText<"Check unchecked local variables.">, Documentation; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 64e9b7aebd1d1..d1de2dbac2a0e 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -4246,13 +4246,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { // decl and its redeclarations may be required. } - StringLiteral *Msg = D->getDeletedMessage(); - if (Msg) { - auto Imported = import(Msg); - if (!Imported) - return Imported.takeError(); - Msg = *Imported; - } + // We will import DefaultedOrDeletedInfo later. ToFunction->setQualifierInfo(ToQualifierLoc); ToFunction->setAccess(D->getAccess()); @@ -4271,10 +4265,28 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { ToFunction->setRangeEnd(ToEndLoc); ToFunction->setDefaultLoc(ToDefaultLoc); - if (Msg) + if (auto *Info = D->getDefaultedOrDeletedInfo()) { + StringLiteral *Msg = nullptr; + if (StringLiteral *M = Info->getDeletedMessage()) { + auto Imported = import(M); + if (!Imported) + return Imported.takeError(); + Msg = *Imported; + } + + SmallVector Lookups; + for (DeclAccessPair P : Info->getUnqualifiedLookups()) { + auto Imported = import(P.getDecl()); + if (!Imported) + return Imported.takeError(); + Lookups.push_back( + DeclAccessPair::make(cast(*Imported), P.getAccess())); + } + ToFunction->setDefaultedOrDeletedInfo( FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( - Importer.getToContext(), {}, Msg)); + Importer.getToContext(), Lookups, Info->getFPFeatures(), Msg)); + } // Set the parameters. for (auto *Param : Parameters) { diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index b2af27fc88542..0adcdfe6e78c9 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1110,8 +1110,10 @@ static bool diagnoseCallableDecl(InterpState &S, CodePtr OpPC, diag::note_constexpr_invalid_function, 1) << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; - if (DiagDecl->getDefinition()) - S.Note(DiagDecl->getDefinition()->getLocation(), diag::note_declared_at); + const FunctionDecl *Definition; + const Stmt *Body = DiagDecl->getBody(Definition); + if (Body && Definition) + S.Note(Definition->getLocation(), diag::note_declared_at); else S.Note(DiagDecl->getLocation(), diag::note_declared_at); } diff --git a/clang/lib/AST/ByteCode/MemberPointer.cpp b/clang/lib/AST/ByteCode/MemberPointer.cpp index f0c1fe5930261..bccadc4d4fc8f 100644 --- a/clang/lib/AST/ByteCode/MemberPointer.cpp +++ b/clang/lib/AST/ByteCode/MemberPointer.cpp @@ -89,8 +89,20 @@ APValue MemberPointer::toAPValue(const ASTContext &ASTCtx) const { ComparisonCategoryResult MemberPointer::compare(const MemberPointer &RHS) const { - if (this->getDecl() == RHS.getDecl()) { + assert(!isZero()); + assert(!RHS.isZero()); + const auto getCmpDecl = [](const MemberPointer &P) -> const Decl * { + const Decl *D = P.getDecl()->getMostRecentDecl(); + if (const auto *FD = dyn_cast(D)) + D = FD->getFirstDecl(); + return D; + }; + + const Decl *LHSCmpDecl = getCmpDecl(*this); + const Decl *RHSCmpDecl = getCmpDecl(RHS); + + if (LHSCmpDecl == RHSCmpDecl) { if (this->PathLength != RHS.PathLength) return ComparisonCategoryResult::Unordered; diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index d73011a8d8dc4..378a190184be9 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -200,9 +200,10 @@ UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init, return std::nullopt; Global *NewGlobal = Globals[*Idx]; - // Note that this loop has one iteration where Redecl == VD. - for (const Decl *Redecl : VD->redecls()) { + GlobalIndices[VD] = *Idx; + for (const Decl *Redecl = VD->getPreviousDecl(); Redecl; + Redecl = Redecl->getPreviousDecl()) { // If this redecl was registered as a dummy variable, it is now a proper // global variable and points to the block we just created. if (auto DummyIt = DummyVariables.find(Redecl); @@ -222,17 +223,15 @@ UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init, continue; } - if (Redecl != VD) { - Block *RedeclBlock = Globals[Iter->second]->block(); - // All pointers pointing to the previous extern decl now point to the - // new decl. - // A previous iteration might've already fixed up the pointers for this - // global. - if (RedeclBlock != NewGlobal->block()) - RedeclBlock->movePointersTo(NewGlobal->block()); + Block *RedeclBlock = Globals[Iter->second]->block(); + // All pointers pointing to the previous extern decl now point to the + // new decl. + // A previous iteration might've already fixed up the pointers for this + // global. + if (RedeclBlock != NewGlobal->block()) + RedeclBlock->movePointersTo(NewGlobal->block()); - Globals[Iter->second] = NewGlobal; - } + Globals[Iter->second] = NewGlobal; Iter->second = *Idx; } diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index b23bf73ae803c..4eaef0d87f3e5 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3116,7 +3116,7 @@ bool FunctionDecl::isVariadic() const { FunctionDecl::DefaultedOrDeletedFunctionInfo * FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( ASTContext &Context, ArrayRef Lookups, - StringLiteral *DeletedMessage) { + FPOptionsOverride FPFeatures, StringLiteral *DeletedMessage) { static constexpr size_t Alignment = std::max({alignof(DefaultedOrDeletedFunctionInfo), alignof(DeclAccessPair), alignof(StringLiteral *)}); @@ -3127,6 +3127,7 @@ FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( new (Context.Allocate(Size, Alignment)) DefaultedOrDeletedFunctionInfo; Info->NumLookups = Lookups.size(); Info->HasDeletedMessage = DeletedMessage != nullptr; + Info->FPFeatures = FPFeatures; llvm::uninitialized_copy(Lookups, Info->getTrailingObjects()); if (DeletedMessage) @@ -3152,7 +3153,7 @@ void FunctionDecl::setDeletedAsWritten(bool D, StringLiteral *Message) { DefaultedOrDeletedInfo->setDeletedMessage(Message); else setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo::Create( - getASTContext(), /*Lookups=*/{}, Message)); + getASTContext(), /*Lookups=*/{}, FPOptionsOverride(), Message)); } } diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index c9a41df806aff..1ecb474c1ede8 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -714,6 +714,14 @@ ParsedTargetAttr PPCTargetInfo::parseTargetAttr(StringRef Features) const { return Ret; } +bool PPCTargetInfo::isValidFeatureName(StringRef Name) const { + // we have some target features that are spelled differently on the command + // line versus what's in PPC.td. We need to continue accepting them. + if (Name == "pcrel" || Name == "prefixed") + return true; + return llvm::PPC::isValidFeatureName(Name); +} + llvm::APInt PPCTargetInfo::getFMVPriority(ArrayRef Features) const { if (Features.empty()) return llvm::APInt(32, 0); diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index e3bf5072d932d..22880e5a04a3f 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -202,6 +202,8 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool isValidFeatureName(StringRef Name) const override; + llvm::APInt getFMVPriority(ArrayRef Features) const override; ArrayRef getGCCRegNames() const override; diff --git a/clang/lib/Basic/Targets/SystemZ.cpp b/clang/lib/Basic/Targets/SystemZ.cpp index 750629ac94f87..080a961b95d0d 100644 --- a/clang/lib/Basic/Targets/SystemZ.cpp +++ b/clang/lib/Basic/Targets/SystemZ.cpp @@ -22,7 +22,9 @@ using namespace clang; using namespace clang::targets; static constexpr int NumBuiltins = - clang::SystemZ::LastTSBuiltin - Builtin::FirstTSBuiltin; + clang::SystemZ::LastSystemZBuiltin - Builtin::FirstTSBuiltin + 1; +static constexpr int NumBuiltinsZOS = + clang::SystemZ::LastTSBuiltin - clang::SystemZ::LastSystemZBuiltin - 1; #define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsSystemZ.inc" @@ -41,6 +43,20 @@ static constexpr Builtin::Info PrefixedBuiltinInfos[] = { }; static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) == NumBuiltins); +namespace clang { +namespace ZOS { +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsZOS.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsZOS.inc" +#undef GET_BUILTIN_INFOS +}; +static_assert((std::size(BuiltinInfos)) == NumBuiltinsZOS); +} // namespace ZOS +} // namespace clang const char *const SystemZTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -216,6 +232,10 @@ void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts, llvm::SmallVector SystemZTargetInfo::getTargetBuiltins() const { + if (getTriple().isOSzOS()) + return {{&BuiltinStrings, BuiltinInfos}, + {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_s390_"}, + {&ZOS::BuiltinStrings, ZOS::BuiltinInfos}}; return {{&BuiltinStrings, BuiltinInfos}, {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_s390_"}}; } diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index dfb5ace82bb06..2608aaf780591 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -2869,22 +2869,20 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, if (cir::isFPOrVectorOfFPType(ty)) intrName = "aarch64.neon.fmax"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vmaxh_f16: - cgm.errorNYI(expr->getSourceRange(), - std::string("unimplemented AArch64 builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); - return mlir::Value{}; + case NEON::BI__builtin_neon_vmaxh_f16: { + auto halfTy = builder.getFp16Ty(); + return builder.emitIntrinsicCallOp(loc, "aarch64.neon.fmax", halfTy, ops); + } case NEON::BI__builtin_neon_vmin_v: case NEON::BI__builtin_neon_vminq_v: intrName = usgn ? "aarch64.neon.umin" : "aarch64.neon.smin"; if (cir::isFPOrVectorOfFPType(ty)) intrName = "aarch64.neon.fmin"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vminh_f16: - cgm.errorNYI(expr->getSourceRange(), - std::string("unimplemented AArch64 builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); - return mlir::Value{}; + case NEON::BI__builtin_neon_vminh_f16: { + auto halfTy = builder.getFp16Ty(); + return builder.emitIntrinsicCallOp(loc, "aarch64.neon.fmin", halfTy, ops); + } case NEON::BI__builtin_neon_vabd_v: case NEON::BI__builtin_neon_vabdq_v: intrName = usgn ? "aarch64.neon.uabd" : "aarch64.neon.sabd"; @@ -2917,16 +2915,18 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, case NEON::BI__builtin_neon_vminnmq_v: intrName = "aarch64.neon.fminnm"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vminnmh_f16: - cgm.errorNYI(expr->getSourceRange(), - std::string("unimplemented AArch64 builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); - return mlir::Value{}; + case NEON::BI__builtin_neon_vminnmh_f16: { + auto halfTy = builder.getFp16Ty(); + return builder.emitIntrinsicCallOp(loc, "aarch64.neon.fminnm", halfTy, ops); + } case NEON::BI__builtin_neon_vmaxnm_v: case NEON::BI__builtin_neon_vmaxnmq_v: intrName = "aarch64.neon.fmaxnm"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vmaxnmh_f16: + case NEON::BI__builtin_neon_vmaxnmh_f16: { + auto halfTy = builder.getFp16Ty(); + return builder.emitIntrinsicCallOp(loc, "aarch64.neon.fmaxnm", halfTy, ops); + } case NEON::BI__builtin_neon_vrecpss_f32: case NEON::BI__builtin_neon_vrecpsd_f64: cgm.errorNYI(expr->getSourceRange(), @@ -3106,11 +3106,10 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, case NEON::BI__builtin_neon_vpminnmq_v: intrName = "aarch64.neon.fminnmp"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vsqrth_f16: - cgm.errorNYI(expr->getSourceRange(), - std::string("unimplemented AArch64 builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); - return mlir::Value{}; + case NEON::BI__builtin_neon_vsqrth_f16: { + auto halfTy = builder.getFp16Ty(); + return emitCallMaybeConstrainedBuiltin(builder, loc, "sqrt", {halfTy}, ops); + } case NEON::BI__builtin_neon_vsqrt_v: case NEON::BI__builtin_neon_vsqrtq_v: assert(!cir::MissingFeatures::emitConstrainedFPCall()); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 88f698f38cce0..18524a7c32b7a 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -7366,17 +7366,50 @@ static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, CGF, S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); - const auto *NT = S.getSingleClause(); - const auto *TL = S.getSingleClause(); - if (NT || TL) { - const Expr *NumTeams = NT ? NT->getNumTeams().front() : nullptr; - const Expr *ThreadLimit = TL ? TL->getThreadLimit().front() : nullptr; + OMPTeamsScope Scope(CGF, S); + auto ParallelLeague = [&S](CodeGenFunction &CGF, PrePostActionTy &) { + const auto *NT = S.getSingleClause(); + const auto *TL = S.getSingleClause(); + if (NT || TL) { + const Expr *NumTeams = NT ? NT->getNumTeams().front() : nullptr; + const Expr *ThreadLimit = TL ? TL->getThreadLimit().front() : nullptr; + + CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit, + S.getBeginLoc()); + } + }; - CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit, - S.getBeginLoc()); + const Expr *IfCond = nullptr; + for (const auto *C : S.getClausesOfKind()) { + if (C->getNameModifier() == OMPD_unknown || + C->getNameModifier() == OMPD_teams) { + IfCond = C->getCondition(); + break; + } + } + if (IfCond && CGF.CGM.getLangOpts().OpenMP >= 52) { + auto SerialLeague = [&S](CodeGenFunction &CGF, PrePostActionTy &) { + // OpenMP 5.2, 10.2, teams Construct + // When an if clause is present on a teams construct and the if clause + // expression evaluates to false, the number of created teams is one. + const llvm::APInt One(32, 1); + IntegerLiteral NumTeams( + CGF.getContext(), One, + CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/0), + SourceLocation()); + // The thread_limit clause is unaffected by the if clause. + const auto *TL = S.getSingleClause(); + const Expr *ThreadLimit = TL ? TL->getThreadLimit().front() : nullptr; + CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, &NumTeams, ThreadLimit, + S.getBeginLoc()); + }; + CGF.CGM.getOpenMPRuntime().emitIfClause(CGF, IfCond, ParallelLeague, + SerialLeague); + } else { + const RegionCodeGenTy ThenRCG(ParallelLeague); + ThenRCG(CGF); } - OMPTeamsScope Scope(CGF, S); llvm::SmallVector CapturedVars; CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getBeginLoc(), OutlinedFn, diff --git a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp index 227a2c4d33bdd..66e4e688e33ee 100644 --- a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp @@ -31,6 +31,22 @@ using namespace llvm; namespace { +static Value *emitAMDGPUSBufferLoadBuiltin(CodeGenFunction &CGF, + const CallExpr *E) { + llvm::Type *RetTy = CGF.ConvertType(E->getType()); + Function *F = CGF.CGM.getIntrinsic(Intrinsic::amdgcn_s_buffer_load, RetTy); + + Value *RsrcPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Type *I128Ty = llvm::IntegerType::get(CGF.getLLVMContext(), 128); + llvm::Type *RsrcVecTy = + llvm::FixedVectorType::get(CGF.Builder.getInt32Ty(), 4); + Value *RsrcInt = CGF.Builder.CreatePtrToInt(RsrcPtr, I128Ty); + Value *Rsrc = CGF.Builder.CreateBitCast(RsrcInt, RsrcVecTy); + + return CGF.Builder.CreateCall(F, {Rsrc, CGF.EmitScalarExpr(E->getArg(1)), + CGF.EmitScalarExpr(E->getArg(2))}); +} + // Has second type mangled argument. static Value * emitBinaryExpMaybeConstrainedFPBuiltin(CodeGenFunction &CGF, const CallExpr *E, @@ -2154,6 +2170,30 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_raw_ptr_buffer_atomic_fmax_f64: return emitBuiltinWithOneOverloadedType<5>( *this, E, Intrinsic::amdgcn_raw_ptr_buffer_atomic_fmax); + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v2i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v3i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v4i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v8i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v16i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v2f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v3f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v4f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v8f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v16f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_i8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_u8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_i16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_u16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v2i8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v3i8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v4i8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_f16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v2f16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v3f16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v4f16: + return emitAMDGPUSBufferLoadBuiltin(*this, E); case AMDGPU::BI__builtin_amdgcn_s_prefetch_data: return emitBuiltinWithOneOverloadedType<2>( *this, E, Intrinsic::amdgcn_s_prefetch_data); diff --git a/clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp b/clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp index c33d7581f50b8..2f8a5e62d6e9f 100644 --- a/clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "CGBuiltin.h" #include "CodeGenFunction.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/IR/IntrinsicsS390.h" @@ -36,6 +37,52 @@ static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF, return CGF.Builder.CreateExtractValue(Call, 0); } +/// For z/OS, the builtin __cs1 has the following signature: +/// int __cs1(void * Comparand, +/// void * Destination, +/// void * Exchange); +/// Whereas the llvm 'cmpxchg' instruction has the following syntax: +/// compxchg *Destination, Comparand, Exchange. +/// So we need to swap Comparand & Destination and dereference Comparand & +/// Exchange when invoking CreateAtomicCmpXchg. For this reason we can not use +/// the utility function MakeAtomicCmpXchgValue. +static Value *EmitAtomicCmpXchgForZOSIntrin(CodeGenFunction &CGF, + const CallExpr *E, + llvm::Type *IntType, bool HasAddr) { + + CharUnits Alignment = + CGF.getContext().toCharUnitsFromBits(IntType->getScalarSizeInBits()); + llvm::Value *ComparandPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *DestinationPtr = CGF.EmitScalarExpr(E->getArg(1)); + + Address DestinationAddr = Address(DestinationPtr, IntType, Alignment); + Address ComparandAddr = Address(ComparandPtr, IntType, Alignment); + + llvm::Value *Comparand = CGF.Builder.CreateLoad(ComparandAddr); + llvm::Value *Exchange; + if (HasAddr) { + llvm::Value *ExchangePtr = CGF.EmitScalarExpr(E->getArg(2)); + Address ExchangeAddr = Address(ExchangePtr, IntType, Alignment); + Exchange = CGF.Builder.CreateLoad(ExchangeAddr); + } else { + Exchange = CGF.EmitScalarExpr(E->getArg(2)); + } + + Value *Result = CGF.Builder.CreateAtomicCmpXchg( + DestinationAddr, Comparand, Exchange, + llvm::AtomicOrdering::SequentiallyConsistent, + llvm::AtomicOrdering::SequentiallyConsistent); + + // Store Destination in Comparand. + CGF.Builder.CreateStore(CGF.Builder.CreateExtractValue(Result, 0), + ComparandAddr); + + // Extract boolean success flag, invert it and zext it to int. + llvm::Value *RetVal = + CGF.Builder.CreateNot(CGF.Builder.CreateExtractValue(Result, 1)); + return CGF.Builder.CreateZExt(RetVal, CGF.ConvertType(E->getType())); +} + Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { switch (BuiltinID) { @@ -68,11 +115,25 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, Function *F = CGM.getIntrinsic(Intrinsic::s390_ntstg); return Builder.CreateCall(F, {Data, Address}); } + case SystemZ::BI__cs: { + return EmitAtomicCmpXchgForZOSIntrin(*this, E, Int32Ty, false); + } + case SystemZ::BI__cs1: { + return EmitAtomicCmpXchgForZOSIntrin(*this, E, Int32Ty, true); + } + case SystemZ::BI__csg: + case SystemZ::BI__cds1: { + return EmitAtomicCmpXchgForZOSIntrin(*this, E, Int64Ty, true); + } + case SystemZ::BI__cdsg: { + llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); + return EmitAtomicCmpXchgForZOSIntrin(*this, E, Int128Ty, true); + } - // Vector builtins. Note that most vector builtins are mapped automatically - // to target-specific LLVM intrinsics. The ones handled specially here can - // be represented via standard LLVM IR, which is preferable to enable common - // LLVM optimizations. + // Vector builtins. Note that most vector builtins are mapped automatically + // to target-specific LLVM intrinsics. The ones handled specially here can + // be represented via standard LLVM IR, which is preferable to enable common + // LLVM optimizations. case SystemZ::BI__builtin_s390_vclzb: case SystemZ::BI__builtin_s390_vclzh: diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 2974cf2660184..75e4f7772f47c 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1679,6 +1679,7 @@ std::unique_ptr ASTUnit::LoadFromCompilerInvocation( // Create the AST unit. std::unique_ptr AST(new ASTUnit(false)); ConfigureDiags(Diags, *AST, CaptureDiagnostics); + *AST->CodeGenOpts = CI->getCodeGenOpts(); AST->DiagOpts = DiagOpts; AST->Diagnostics = Diags; AST->OnlyLocalDecls = OnlyLocalDecls; diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 4bbfb9ba1662a..b1d1832a598d9 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -415,6 +415,7 @@ set(zos_wrapper_files zos_wrappers/locale.h zos_wrappers/math.h zos_wrappers/poll.h + zos_wrappers/stdlib.h zos_wrappers/string.h zos_wrappers/time.h zos_wrappers/variant.h diff --git a/clang/lib/Headers/zos_wrappers/stdlib.h b/clang/lib/Headers/zos_wrappers/stdlib.h new file mode 100644 index 0000000000000..433e1b5ad0b23 --- /dev/null +++ b/clang/lib/Headers/zos_wrappers/stdlib.h @@ -0,0 +1,20 @@ +/*===----------------------------- stdlib.h --------------------------------=== + * + * 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 __ZOS_WRAPPERS_STDLIB_H +#define __ZOS_WRAPPERS_STDLIB_H +#if __has_include_next() +#include_next +#ifdef _EXT +#ifndef __CS1 +#undef __cs +#endif +#endif /* _EXT */ +#endif /* __has_include_next() */ +#endif /* __ZOS_WRAPPERS_STDLIB_H */ diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp b/clang/lib/Interpreter/IncrementalExecutor.cpp index 65cb29a2f441a..8e64a3d73305e 100644 --- a/clang/lib/Interpreter/IncrementalExecutor.cpp +++ b/clang/lib/Interpreter/IncrementalExecutor.cpp @@ -27,6 +27,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" +#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" #include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h" #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h" #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" @@ -60,6 +61,21 @@ #include #endif +// Address of the host's emulated-TLS runtime entry point, or null if the host +// cannot provide one. On Darwin, __emutls_get_address lives in the compiler-rt +// builtins archive; referencing it here force-links the archive member into +// the binary. The reference must not exist elsewhere: MSVC has no emulated-TLS +// runtime (the link would fail), and ELF hosts resolve it from libgcc_s / +// compiler-rt through regular process-symbol lookup. +#ifdef __APPLE__ +extern "C" void *__emutls_get_address(void *); +static void *getEmuTLSGetAddressPtr() { + return reinterpret_cast(&__emutls_get_address); +} +#else +static void *getEmuTLSGetAddressPtr() { return nullptr; } +#endif + namespace clang { IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = default; @@ -388,6 +404,29 @@ IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC, if (!JB) return JB.takeError(); JITBuilder = std::move(*JB); + // TODO: Switch to native TLS on Darwin once clang-repl can adopt the ORC + // runtime (which provides __emutls_get_address and supports the full TLS + // lifecycle). That will also remove the in-process-only constraint below. + // + // For MachO targets, thread_locals are lowered to emulated TLS, but the + // runtime (__emutls_get_address) lives in the compiler-rt builtins archive + // and nothing else in this process references it, so it isn't linked in + // and process-symbol lookup cannot find it. Define the force-linked host + // symbol (see getEmuTLSGetAddressPtr) as an absolute symbol so it is + // visible to JIT'd code. In-process execution only: the address is + // meaningless in an out-of-process executor. + if (void *EmuTLSGetAddress = getEmuTLSGetAddressPtr(); + EmuTLSGetAddress && TT.isOSBinFormatMachO()) + JITBuilder->setNotifyCreatedCallback( + [EmuTLSGetAddress](llvm::orc::LLJIT &J) { + auto &JD = J.getProcessSymbolsJITDylib() + ? *J.getProcessSymbolsJITDylib() + : J.getMainJITDylib(); + return JD.define(llvm::orc::absoluteSymbols( + {{J.mangleAndIntern("__emutls_get_address"), + {llvm::orc::ExecutorAddr::fromPtr(EmuTLSGetAddress), + llvm::JITSymbolFlags::Exported}}})); + }); } llvm::Error Err = llvm::Error::success(); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 3f41e7c5c6f0d..7326ba781184c 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3282,8 +3282,8 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, DSContext == DeclSpecContext::DSC_top_level); if (getLangOpts().CPlusPlus && - Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype, - tok::annot_template_id) && + (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype) || + (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon))) && TryAnnotateCXXScopeToken(EnteringContext)) { SkipMalformedDecl(); return true; diff --git a/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp b/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp index 667ef69606aad..d9a168e11d1a7 100644 --- a/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp +++ b/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp @@ -12,7 +12,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/ExprCXX.h" -#include +#include "llvm/ADT/SetVector.h" using namespace clang; @@ -32,7 +32,7 @@ namespace { // Traverses the AST and finds contributors. class ContributorFinder : public DynamicRecursiveASTVisitor { public: - std::set Contributors; + llvm::SetVector Contributors; ContributorFinder() { ShouldVisitTemplateInstantiations = true; diff --git a/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h b/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h index 152168ea73b54..05c71ed83853b 100644 --- a/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h +++ b/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h @@ -110,9 +110,9 @@ void extractAndAddSummaries(TUSummaryExtractor &Extractor, findContributors(Ctx, Contributors); for (const auto &[Cano, Decls] : Contributors) { assert(!Decls.empty() && - "'findContributors' guarantess that 'Decls' are non-empty"); + "'findContributors' guarantees that 'Decls' are non-empty"); assert(!Decls[0]->isImplicit() && - "'findContributors' guarantess that 'Decls' are non-implicit"); + "'findContributors' guarantees that 'Decls' are non-implicit"); // Templates are skipped, but their instantiations are handled. The idea // is that we can conclude facts about a template through all of its diff --git a/clang/lib/ScalableStaticAnalysis/SourceTransformation/CMakeLists.txt b/clang/lib/ScalableStaticAnalysis/SourceTransformation/CMakeLists.txt index f46b6df1d0bdb..25db2fb7eca7d 100644 --- a/clang/lib/ScalableStaticAnalysis/SourceTransformation/CMakeLists.txt +++ b/clang/lib/ScalableStaticAnalysis/SourceTransformation/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS ) add_clang_library(clangScalableStaticAnalysisSourceTransformation + SARIFTransformationReportFormat.cpp TransformationRegistry.cpp YAMLSourceEditFormat.cpp diff --git a/clang/lib/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.cpp b/clang/lib/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.cpp new file mode 100644 index 0000000000000..d5993d2c0345a --- /dev/null +++ b/clang/lib/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.cpp @@ -0,0 +1,56 @@ +//===- SARIFTransformationReportFormat.cpp --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h" +#include "clang/Basic/Sarif.h" +#include "clang/Basic/Version.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/JSON.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; +using namespace ssaf; + +llvm::Error ssaf::writeSARIFTransformationReport(const ReportDocument &Doc, + llvm::StringRef Path) { + std::error_code EC; + llvm::raw_fd_ostream OS(Path, EC, llvm::sys::fs::OF_None); + if (EC) + return llvm::createStringError(EC, "failed to open '" + Path + "'"); + + clang::SarifDocumentWriter Writer(Doc.SM); + std::string LongToolName = + "clang ScalableStaticAnalysisFramework source transformation (" + + Doc.TransformationName + ")"; + Writer.createRun("clang-ssaf", LongToolName, CLANG_VERSION_STRING); + + llvm::StringMap RuleIndex; + for (const ReportResult &R : Doc.Results) { + if (RuleIndex.contains(R.RuleId)) + continue; + RuleIndex[R.RuleId] = + Writer.createRule(clang::SarifRule::create().setRuleId(R.RuleId)); + } + + for (const ReportResult &R : Doc.Results) { + clang::SarifResult Result = clang::SarifResult::create(RuleIndex[R.RuleId]) + .setRuleId(R.RuleId) + .setDiagnosticMessage(R.Message) + .setDiagnosticLevel(R.Level); + if (R.Range.isValid()) + Result = Result.addLocations({R.Range}); + Writer.appendResult(Result); + } + + llvm::json::Value Document(Writer.createDocument()); + OS << llvm::formatv("{0:2}", Document) << "\n"; + return llvm::Error::success(); +} diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1d2a3983a639d..115795ca74bae 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -281,6 +281,22 @@ static BuiltinTypeDeclBuilder setupTextureType(CXXRecordDecl *Decl, Sema &S, .addGatherCmpMethods(Dim, IsArray); } +/// Set up RWTexture type: UAV texture with only operator[] (uint2, read/write), +/// Load and GetDimensions (no sample/gather/mips/LOD). +static BuiltinTypeDeclBuilder setupRWTextureType(CXXRecordDecl *Decl, Sema &S, + bool IsArray, + ResourceDimension Dim) { + return BuiltinTypeDeclBuilder(S, Decl) + .addTextureHandle(ResourceClass::UAV, /*IsROV=*/false, IsArray, Dim) + .addTextureLoadMethods(Dim, IsArray) + .addArraySubscriptOperators(Dim, IsArray) + .addGetDimensionsMethods(Dim) + .addDefaultHandleConstructor() + .addCopyConstructor() + .addCopyAssignmentOperator() + .addStaticInitializationFunctions(false); +} + // Add a partial specialization for a template. The `TextureTemplate` is // `Texture`, and it will be specialized for vectors: // `Texture>`. @@ -691,6 +707,25 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { .completeDefinition(); }); + Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWTexture2D") + .addSimpleTemplateParams({"element_type"}, {Float4Ty}, + TypedBufferConcept) + .finalizeForwardDeclaration(); + + onCompletion(Decl, [this](CXXRecordDecl *Decl) { + setupRWTextureType(Decl, *SemaPtr, /*IsArray=*/false, + ResourceDimension::Dim2D) + .completeDefinition(); + }); + + auto *PartialSpecRW = addVectorTexturePartialSpecialization( + *SemaPtr, HLSLNamespace, Decl->getDescribedClassTemplate()); + onCompletion(PartialSpecRW, [this](CXXRecordDecl *Decl) { + setupRWTextureType(Decl, *SemaPtr, /*IsArray=*/false, + ResourceDimension::Dim2D) + .completeDefinition(); + }); + // Texture2DArray — same as Texture2D but IsArray=true Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "Texture2DArray") .addSimpleTemplateParams({"element_type"}, {Float4Ty}, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 2fc4fac6d5351..d1ddd3f6a1cc2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11046,6 +11046,25 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (NewFD->hasAttr()) HLSL().CheckEntryPoint(NewFD); + + // Resources cannot be passed to functions that are not inlined. + if (const NoInlineAttr *NoInline = NewFD->getAttr()) { + for (const ParmVarDecl *PVD : NewFD->parameters()) { + QualType ParamTy = PVD->getType().getNonReferenceType(); + QualType EltTy = Context.getBaseElementType(ParamTy); + // `isCompleteType` forces completion of the element type without + // reporting an error (diagnosed elsewhere) so the resource parameter + // check is valid. + if (!EltTy->isDependentType() && + isCompleteType(PVD->getLocation(), EltTy) && + ParamTy->isHLSLIntangibleType()) { + Diag(PVD->getLocation(), + diag::err_hlsl_resource_param_in_noinline_function) + << ParamTy; + Diag(NoInline->getLocation(), diag::note_attribute); + } + } + } } // If this is the first declaration of a library builtin function, add @@ -15770,11 +15789,17 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D, } // Incomplete resource arrays are not allowed as function parameters in HLSL - if (getLangOpts().HLSL && parmDeclType->isIncompleteArrayType() && - parmDeclType->isHLSLResourceRecordArray()) { - Diag(D.getIdentifierLoc(), - diag::err_hlsl_incomplete_resource_array_in_function_param); - D.setInvalidType(true); + if (getLangOpts().HLSL && parmDeclType->isIncompleteArrayType()) { + QualType EltTy = Context.getBaseElementType(parmDeclType); + // `isCompleteType` forces completion of the element type so the resource + // check is valid. + if (!EltTy->isDependentType() && + isCompleteType(D.getIdentifierLoc(), EltTy) && + parmDeclType->isHLSLResourceRecordArray()) { + Diag(D.getIdentifierLoc(), + diag::err_hlsl_incomplete_resource_array_in_function_param); + D.setInvalidType(true); + } } // Temporarily put parameter variables in the translation unit, not diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 914c714ded9c4..a2054a1b0bd04 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3905,6 +3905,13 @@ static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } + // If a declaration contains multiple cleanup attributes, GCC only uses + // the last one. + if (const auto *A = D->getAttr()) { + S.Diag(A->getLoc(), diag::warn_duplicate_cleanup_attr) << A->getRange(); + D->dropAttr(); + } + auto *attr = ::new (S.Context) CleanupAttr(S.Context, AL, FD); attr->setArgLoc(E->getExprLoc()); D->addAttr(attr); @@ -9028,7 +9035,7 @@ void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { void Sema::ActOnCleanupAttr(Decl *D, const Attr *A) { VarDecl *VD = cast(D); - if (VD->getType()->isDependentType()) + if (VD->isInvalidDecl() || VD->getType()->isDependentType()) return; // Obtains the FunctionDecl that was found when handling the attribute diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 65b46562b166e..15c3b04942825 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6906,6 +6906,25 @@ Sema::getDefaultedFunctionKind(const FunctionDecl *FD) { return DefaultedFunctionKind(); } +namespace { +/// RAII object to restore the floating-point (FP) features active at the time +/// a defaulted function was declared. This ensures that the synthesized body +/// of the function respects the FP pragmas (e.g., #pragma STDC FENV_ACCESS) +/// that were in effect when the function was explicitly defaulted. +struct DefaultedFunctionFPFeaturesRAII { + Sema::FPFeaturesStateRAII SavedFPFeatures; + DefaultedFunctionFPFeaturesRAII(Sema &S, FunctionDecl *FD) + : SavedFPFeatures(S) { + auto *Info = FD->getDefaultedOrDeletedInfo(); + FPOptionsOverride FPO = Info ? Info->getFPFeatures() : FPOptionsOverride(); + S.CurFPFeatures = FPO.applyOverrides(S.LangOpts); + S.FpPragmaStack.CurrentValue = FPO; + } + + ~DefaultedFunctionFPFeaturesRAII() = default; +}; +} // namespace + static void DefineDefaultedFunction(Sema &S, FunctionDecl *FD, SourceLocation DefaultLoc) { Sema::DefaultedFunctionKind DFK = S.getDefaultedFunctionKind(FD); @@ -9029,7 +9048,7 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD, FD->getOverloadedOperator()); FD->setDefaultedOrDeletedInfo( FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( - Context, Operators.pairs())); + Context, Operators.pairs(), CurFPFeatureOverrides())); } // C++2a [class.compare.default]p1: @@ -9374,6 +9393,8 @@ void Sema::DefineDefaultedComparison(SourceLocation UseLoc, FunctionDecl *FD, // Add a context note for diagnostics produced after this point. Scope.addContextNote(UseLoc); + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, FD); + { // Build and set up the function body. // The first parameter has type maybe-ref-to maybe-const T, use that to get @@ -14367,6 +14388,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, Constructor); assert((Constructor->isDefaulted() && Constructor->isDefaultConstructor() && !Constructor->doesThisDeclarationHaveABody() && !Constructor->isDeleted()) && @@ -14666,6 +14688,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) { void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, Destructor); assert((Destructor->isDefaulted() && !Destructor->doesThisDeclarationHaveABody() && !Destructor->isDeleted()) && @@ -15356,6 +15379,7 @@ static void diagnoseDeprecatedCopyOperation(Sema &S, CXXMethodDecl *CopyOp) { void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, CXXMethodDecl *CopyAssignOperator) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, CopyAssignOperator); assert((CopyAssignOperator->isDefaulted() && CopyAssignOperator->isOverloadedOperator() && CopyAssignOperator->getOverloadedOperator() == OO_Equal && @@ -15743,6 +15767,7 @@ static void checkMoveAssignmentForRepeatedMove(Sema &S, CXXRecordDecl *Class, void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, CXXMethodDecl *MoveAssignOperator) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, MoveAssignOperator); assert((MoveAssignOperator->isDefaulted() && MoveAssignOperator->isOverloadedOperator() && MoveAssignOperator->getOverloadedOperator() == OO_Equal && @@ -16076,6 +16101,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *CopyConstructor) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, CopyConstructor); assert((CopyConstructor->isDefaulted() && CopyConstructor->isCopyConstructor() && !CopyConstructor->doesThisDeclarationHaveABody() && @@ -16214,6 +16240,7 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor( void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *MoveConstructor) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, MoveConstructor); assert((MoveConstructor->isDefaulted() && MoveConstructor->isMoveConstructor() && !MoveConstructor->doesThisDeclarationHaveABody() && @@ -18776,6 +18803,16 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { return; } + // Only allocate DefaultedOrDeletedFunctionInfo if we actually have + // non-default FP features to stash. This avoids memory overhead for + // the vast majority of defaulted functions. + if (!FD->getDefaultedOrDeletedInfo() && + CurFPFeatureOverrides().requiresTrailingStorage()) { + FD->setDefaultedOrDeletedInfo( + FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( + Context, /*Lookups=*/{}, CurFPFeatureOverrides())); + } + if (DefKind.isComparison()) { if (CheckExplicitlyDefaultedComparison(nullptr, FD, DefKind.asComparison())) FD->setInvalidDecl(); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index ad0e653e254dd..a7f252be1cb39 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -515,7 +515,25 @@ bool Sema::LookupTemplateName(LookupResult &Found, Scope *S, CXXScopeSpec &SS, // to correct any typos. DeclarationName Name = Found.getLookupName(); Found.clear(); - QualifiedLookupValidatorCCC FilterCCC(!SS.isEmpty()); + + class TemplateNameLookupValidatorCCC final + : public QualifiedLookupValidatorCCC { + public: + using QualifiedLookupValidatorCCC::QualifiedLookupValidatorCCC; + + bool ValidateCandidate(const TypoCorrection &Candidate) final { + if (const NamedDecl *ND = Candidate.getCorrectionDecl(); + !ND || !isa(ND)) + return false; + return QualifiedLookupValidatorCCC::ValidateCandidate(Candidate); + } + + std::unique_ptr clone() final { + return std::make_unique(*this); + } + }; + + TemplateNameLookupValidatorCCC FilterCCC(!SS.isEmpty()); FilterCCC.WantTypeSpecifiers = false; FilterCCC.WantExpressionKeywords = false; FilterCCC.WantRemainingKeywords = false; @@ -9303,6 +9321,7 @@ bool Sema::CheckConceptUseInDefinition(NamedDecl *Concept, SourceLocation Loc) { CE && !CE->isInvalidDecl() && !CE->hasDefinition()) { Diag(Loc, diag::err_recursive_concept) << CE; Diag(CE->getLocation(), diag::note_declared_at); + CE->setInvalidDecl(); return true; } // Concept template parameters don't have a definition and can't diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index c56203f10ac3c..a787d537f02f8 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5515,11 +5515,10 @@ bool TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New, Lookups.push_back(DeclAccessPair::make(D, DA.getAccess())); } - // It's unlikely that substitution will change any declarations. Don't - // store an unnecessary copy in that case. New->setDefaultedOrDeletedInfo( AnyChanged ? FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( - SemaRef.Context, Lookups) + SemaRef.Context, Lookups, DFI->getFPFeatures(), + DFI->getDeletedMessage()) : DFI); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index bd684b89e194f..f484bc7e0bf55 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1094,6 +1094,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { StringLiteral *DeletedMessage = HasMessage ? cast(Record.readExpr()) : nullptr; + FPOptionsOverride FPFeatures = + FPOptionsOverride::getFromOpaqueInt(Record.readInt()); + unsigned NumLookups = Record.readInt(); SmallVector Lookups; for (unsigned I = 0; I != NumLookups; ++I) { @@ -1104,7 +1107,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setDefaultedOrDeletedInfo( FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( - Reader.getContext(), Lookups, DeletedMessage)); + Reader.getContext(), Lookups, FPFeatures, DeletedMessage)); } } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index f271769d8edf6..e3b81650d65a1 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -898,6 +898,8 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { if (DeletedMessage) Record.AddStmt(DeletedMessage); + Record.push_back(FDI->getFPFeatures().getAsOpaqueInt()); + Record.push_back(FDI->getUnqualifiedLookups().size()); for (DeclAccessPair P : FDI->getUnqualifiedLookups()) { Record.AddDeclRef(P.getDecl()); diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 7ea028246a2ee..287824984623c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -547,7 +547,7 @@ class MallocChecker {{CDM::CLibrary, {"strdup"}, 1}, &MallocChecker::checkStrdup}, {{CDM::CLibrary, {"_strdup"}, 1}, &MallocChecker::checkStrdup}, {{CDM::CLibrary, {"kmalloc"}, 2}, &MallocChecker::checkKernelMalloc}, - {{CDM::CLibrary, {"if_nameindex"}, 1}, &MallocChecker::checkIfNameIndex}, + {{CDM::CLibrary, {"if_nameindex"}, 0}, &MallocChecker::checkIfNameIndex}, {{CDM::CLibrary, {"wcsdup"}, 1}, &MallocChecker::checkStrdup}, {{CDM::CLibrary, {"_wcsdup"}, 1}, &MallocChecker::checkStrdup}, {{CDM::CLibrary, {"g_malloc"}, 1}, &MallocChecker::checkBasicAlloc}, diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp index 287c7dd039dd8..013608c0ff32c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp @@ -1,4 +1,4 @@ -//=======- UncountedLambdaCapturesChecker.cpp --------------------*- C++ -*-==// +//=======- RawPtrRefLambdaCapturesChecker.cpp --------------------*- C++ -*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -36,7 +36,7 @@ class RawPtrRefLambdaCapturesChecker virtual std::optional isUnsafePtr(QualType) const = 0; virtual bool isPtrType(const std::string &) const = 0; - virtual const char *ptrKind(QualType QT) const = 0; + virtual const char *typeName() const = 0; void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, BugReporter &BRArg) const { @@ -542,25 +542,40 @@ class RawPtrRefLambdaCapturesChecker SmallString<100> Buf; llvm::raw_svector_ostream Os(Buf); - if (Capture.isExplicit()) { + if (Capture.isExplicit()) Os << "Captured "; - } else { + else Os << "Implicitly captured "; - } - if (isa(T) || isa(T)) { - Os << "raw-pointer "; - } else { - Os << "reference "; - } - + Os << "variable "; printQuotedQualifiedName(Os, CapturedVar); - Os << " to " << ptrKind(T) << " type is unsafe."; + + bool IsUnsafePtr = CapturedVar->getType() == T; + if (IsUnsafePtr) + Os << " is a "; + else + Os << " contains a "; + auto *CapturedType = T.getTypePtrOrNull(); + printPointer(Os, CapturedType); PathDiagnosticLocation BSLoc(Location, BR->getSourceManager()); auto Report = std::make_unique(Bug, Os.str(), BSLoc); BR->emitReport(std::move(Report)); } + ObjCInterfaceDecl *getObjCDecl(const Type *TypePtr) const { + auto *PointeeType = TypePtr->getPointeeType().getTypePtrOrNull(); + if (!PointeeType) + return nullptr; + auto *Desugared = PointeeType->getUnqualifiedDesugaredType(); + if (!Desugared) + return nullptr; + if (auto *ObjCType = dyn_cast(Desugared)) + return ObjCType->getDecl(); + if (auto *ObjCType = dyn_cast(Desugared)) + return ObjCType->getInterface(); + return nullptr; + } + void reportBugOnThisPtr(const LambdaCapture &Capture, const QualType T) const { SmallString<100> Buf; @@ -572,41 +587,66 @@ class RawPtrRefLambdaCapturesChecker Os << "Implicitly captured "; } - Os << "raw-pointer 'this' to " << ptrKind(T) << " type is unsafe."; + Os << "variable 'this' is a raw pointer to " << typeName(); + if (auto *RD = T->getPointeeCXXRecordDecl()) { + Os << " "; + printQuotedQualifiedName(Os, RD); + } PathDiagnosticLocation BSLoc(Capture.getLocation(), BR->getSourceManager()); auto Report = std::make_unique(Bug, Os.str(), BSLoc); BR->emitReport(std::move(Report)); } + + virtual void printPointer(llvm::raw_svector_ostream &Os, + const Type *T) const { + T = T->getUnqualifiedDesugaredType(); + bool IsPtr = isa(T) || isa(T); + Os << (IsPtr ? "raw pointer" : "raw reference") << " to "; + Os << typeName(); + + if (auto *RD = T->getPointeeType()->getAsRecordDecl()) { + Os << " "; + printQuotedQualifiedName(Os, RD); + } else if (auto *ObjCDecl = getObjCDecl(T)) { + Os << " "; + printQuotedQualifiedName(Os, ObjCDecl); + } + } }; class UncountedLambdaCapturesChecker : public RawPtrRefLambdaCapturesChecker { public: UncountedLambdaCapturesChecker() - : RawPtrRefLambdaCapturesChecker("Lambda capture of uncounted or " - "unchecked variable") {} + : RawPtrRefLambdaCapturesChecker("Lambda capture of uncounted variable") { + } std::optional isUnsafePtr(QualType QT) const final { - auto result1 = isUncountedPtr(QT); - auto result2 = isUncheckedPtr(QT); - if (result1 && *result1) - return true; - if (result2 && *result2) - return true; - if (result1) - return *result1; - return result2; + return isUncountedPtr(QT.getCanonicalType()); } virtual bool isPtrType(const std::string &Name) const final { - return isRefType(Name) || isCheckedPtr(Name); + return isRefType(Name); + } + + const char *typeName() const final { return "ref-countable type"; } +}; + +class UncheckedLambdaCapturesChecker : public RawPtrRefLambdaCapturesChecker { +public: + UncheckedLambdaCapturesChecker() + : RawPtrRefLambdaCapturesChecker("Lambda capture of unchecked variable") { } - const char *ptrKind(QualType QT) const final { - if (isUncounted(QT)) - return "uncounted"; - return "unchecked"; + std::optional isUnsafePtr(QualType QT) const final { + return isUncheckedPtr(QT.getCanonicalType()); } + + virtual bool isPtrType(const std::string &Name) const final { + return isCheckedPtr(Name); + } + + const char *typeName() const final { return "CheckedPtr capable type"; } }; class UnretainedLambdaCapturesChecker : public RawPtrRefLambdaCapturesChecker { @@ -627,7 +667,30 @@ class UnretainedLambdaCapturesChecker : public RawPtrRefLambdaCapturesChecker { return isRetainPtrOrOSPtr(Name); } - const char *ptrKind(QualType QT) const final { return "unretained"; } + const char *typeName() const final { return "retainable type"; } + + void printPointer(llvm::raw_svector_ostream &Os, const Type *T) const final { + if (auto *ObjCPtr = dyn_cast(T)) { + for (ObjCProtocolDecl *P : ObjCPtr->quals()) { + if (const auto *II = P->getIdentifier()) { + auto Name = II->getName(); + if (Name.starts_with("OS_")) { + Os << typeName() << " "; + printQuotedQualifiedName(Os, P); + return; + } + } + } + } + if (!isa(T) && T->getAs()) { + auto Typedef = T->getAs(); + assert(Typedef); + Os << typeName() << " "; + printQuotedQualifiedName(Os, Typedef->getDecl()); + return; + } + return RawPtrRefLambdaCapturesChecker::printPointer(Os, T); + } }; } // namespace @@ -641,6 +704,15 @@ bool ento::shouldRegisterUncountedLambdaCapturesChecker( return true; } +void ento::registerUncheckedLambdaCapturesChecker(CheckerManager &Mgr) { + Mgr.registerChecker(); +} + +bool ento::shouldRegisterUncheckedLambdaCapturesChecker( + const CheckerManager &mgr) { + return true; +} + void ento::registerUnretainedLambdaCapturesChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp index 0e23ae34ea212..bac15bc31e048 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp @@ -40,7 +40,6 @@ class RawPtrRefMemberChecker virtual std::optional isUnsafePtr(QualType, bool ignoreARC = false) const = 0; virtual const char *typeName() const = 0; - virtual const char *invariant() const = 0; void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, BugReporter &BRArg) const { @@ -291,8 +290,9 @@ class RawPtrRefMemberChecker } else Os << "Member variable "; printQuotedName(Os, Member); - Os << " in "; + Os << " (of "; printQuotedQualifiedName(Os, ClassCXXRD); + Os << ")"; if (Member->getType().getTypePtrOrNull() == MemberType) Os << " is a "; else @@ -303,7 +303,6 @@ class RawPtrRefMemberChecker printQuotedQualifiedName(Os, Typedef->getDecl()); } else printQuotedQualifiedName(Os, Pointee); - Os << "; " << invariant() << "."; PathDiagnosticLocation BSLoc(Member->getSourceRange().getBegin(), BR->getSourceManager()); @@ -332,11 +331,7 @@ class NoUncountedMemberChecker final : public RawPtrRefMemberChecker { return isUncountedPtr(QT.getCanonicalType()); } - const char *typeName() const final { return "ref-countable type"; } - - const char *invariant() const final { - return "member variables must be Ref, RefPtr, WeakRef, or WeakPtr"; - } + const char *typeName() const final { return "RefPtr-capable type"; } }; class NoUncheckedPtrMemberChecker final : public RawPtrRefMemberChecker { @@ -349,12 +344,7 @@ class NoUncheckedPtrMemberChecker final : public RawPtrRefMemberChecker { return isUncheckedPtr(QT.getCanonicalType()); } - const char *typeName() const final { return "CheckedPtr capable type"; } - - const char *invariant() const final { - return "member variables must be a CheckedPtr, CheckedRef, WeakRef, or " - "WeakPtr"; - } + const char *typeName() const final { return "CheckedPtr-capable type"; } }; class NoUnretainedMemberChecker final : public RawPtrRefMemberChecker { @@ -371,11 +361,7 @@ class NoUnretainedMemberChecker final : public RawPtrRefMemberChecker { return RTC->isUnretained(QT, ignoreARC); } - const char *typeName() const final { return "retainable type"; } - - const char *invariant() const final { - return "member variables must be a RetainPtr or OSObjectPtr"; - } + const char *typeName() const final { return "RetainPtr-capable type"; } PrintDeclKind printPointer(llvm::raw_svector_ostream &Os, const Type *T) const final { diff --git a/clang/test/AST/ByteCode/invalid.cpp b/clang/test/AST/ByteCode/invalid.cpp index e79b698a32719..930565181b202 100644 --- a/clang/test/AST/ByteCode/invalid.cpp +++ b/clang/test/AST/ByteCode/invalid.cpp @@ -218,3 +218,12 @@ namespace InvalidVirtualCast { static_assert((X *)(Y *)&z, ""); // both-error {{not an integral constant expression}} \ // both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} } + +namespace DefinitionInBody { + int foo(); // both-note {{declared here}} + int foo() { + static_assert(foo() == 1); // both-error {{not an integral constant expression}} \ + // both-note {{non-constexpr function 'foo' cannot be used in a constant expression}} + return 5; + } +} diff --git a/clang/test/AST/HLSL/Texture2D-AST.hlsl b/clang/test/AST/HLSL/Texture2D-AST.hlsl new file mode 100644 index 0000000000000..23d0b8138b39b --- /dev/null +++ b/clang/test/AST/HLSL/Texture2D-AST.hlsl @@ -0,0 +1,178 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | FileCheck %s --check-prefixes=CHECK,SRV -DTEXTURE=Texture2D -DSZ=2 -DKIND=SRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s | FileCheck %s --check-prefixes=CHECK,SRV,SRV-ARR -DTEXTURE=Texture2DArray -DSZ=3 -DKIND=SRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -DRW=1 -o - %s | FileCheck %s --check-prefixes=CHECK,UAV,UAV-STORE,UAV-TRUNC -DTEXTURE=RWTexture2D -DSZ=2 -DKIND=UAV + +// CHECK: ClassTemplateDecl {{.*}} [[TEXTURE]] +// CHECK: TemplateTypeParmDecl {{.*}} element_type +// CHECK: CXXRecordDecl {{.*}} [[TEXTURE]] definition +// CHECK: FinalAttr {{.*}} Implicit final +// CHECK-NEXT: FieldDecl {{.*}} implicit __handle '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] + +// SRV: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(vector) const' inline +// SRV-NEXT: ParmVarDecl {{.*}} Index 'vector' +// SRV-NEXT: CompoundStmt +// SRV-NEXT: ReturnStmt +// SRV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' cannot overflow +// SRV-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *' +// SRV-NEXT: CallExpr {{.*}} '' +// SRV-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// SRV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// SRV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// SRV-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// SRV-SAME: ' lvalue .__handle +// SRV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[TEXTURE]]' lvalue implicit this +// SRV-NEXT: DeclRefExpr {{.*}} 'vector' lvalue ParmVar {{.*}} 'Index' 'vector' +// SRV-NEXT: AlwaysInlineAttr + +// UAV: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(vector) const' inline +// UAV-NEXT: ParmVarDecl {{.*}} Index 'vector' +// UAV-NEXT: CompoundStmt +// UAV-NEXT: ReturnStmt +// UAV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' cannot overflow +// UAV-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *' +// UAV-NEXT: CallExpr {{.*}} '' +// UAV-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// UAV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// UAV-SAME: ' lvalue .__handle +// UAV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[TEXTURE]]' lvalue implicit this +// UAV-NEXT: DeclRefExpr {{.*}} 'vector' lvalue ParmVar {{.*}} 'Index' 'vector' +// UAV-NEXT: AlwaysInlineAttr + +// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out unsigned int, out unsigned int)' +// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CallExpr {{.*}} '' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getdimensions_xy' 'void (__hlsl_resource_t, unsigned int &, unsigned int &) noexcept' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// CHECK-SAME: ' lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict' +// CHECK-NEXT: AlwaysInlineAttr + +// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out unsigned int, out unsigned int, out unsigned int)' +// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CallExpr {{.*}} '' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy' 'void (__hlsl_resource_t, unsigned int, unsigned int &, unsigned int &, unsigned int &) noexcept' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// CHECK-SAME: ' lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'numberOfLevels' 'unsigned int &__restrict' +// CHECK-NEXT: AlwaysInlineAttr + +// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out float, out float)' +// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CallExpr {{.*}} '' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getdimensions_xy_float' 'void (__hlsl_resource_t, float &, float &) noexcept' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// CHECK-SAME: ' lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict' +// CHECK-NEXT: AlwaysInlineAttr + +// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out float, out float, out float)' +// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CallExpr {{.*}} '' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy_float' 'void (__hlsl_resource_t, unsigned int, float &, float &, float &) noexcept' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// CHECK-SAME: ' lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'numberOfLevels' 'float &__restrict' +// CHECK-NEXT: AlwaysInlineAttr + +// CHECK: ClassTemplatePartialSpecializationDecl {{.*}} class [[TEXTURE]] explicit_specialization +// CHECK: TemplateTypeParmDecl {{.*}} element_type +// CHECK: NonTypeTemplateParmDecl {{.*}} element_count + +// SRV-NOT: BinaryOperator {{.*}} 'hlsl_device float' lvalue '=' + +// UAV-STORE-LABEL: FunctionDecl {{.*}} main 'void ()' +// UAV-STORE: BinaryOperator {{.*}} 'hlsl_device float' lvalue '=' +// UAV-STORE-NEXT: CXXOperatorCallExpr {{.*}} 'hlsl_device float' lvalue '[]' +// UAV-STORE-NEXT: ImplicitCastExpr {{.*}} 'hlsl_device float &(*)(vector) const' +// UAV-STORE-NEXT: DeclRefExpr {{.*}} 'hlsl_device float &(vector) const' lvalue CXXMethod {{.*}} 'operator[]' 'hlsl_device float &(vector) const' +// UAV-STORE-NEXT: ImplicitCastExpr {{.*}} 'const hlsl::[[TEXTURE]]' lvalue +// UAV-STORE-NEXT: DeclRefExpr {{.*}} '[[TEXTURE]]':'hlsl::[[TEXTURE]]' lvalue Var {{.*}} 't' '[[TEXTURE]]':'hlsl::[[TEXTURE]]' +// UAV-TRUNC-NEXT: ImplicitCastExpr {{.*}} 'vector' +// UAV-TRUNC-NEXT: ImplicitCastExpr {{.*}} 'uint3':'vector' +// UAV-TRUNC-NEXT: DeclRefExpr {{.*}} 'uint3':'vector' lvalue Var {{.*}} 'i' 'uint3':'vector' +// UAV-NOTRUNC-NEXT: ImplicitCastExpr {{.*}} 'uint3':'vector' +// UAV-NOTRUNC-NEXT: DeclRefExpr {{.*}} 'uint3':'vector' lvalue Var {{.*}} 'i' 'uint3':'vector' +// UAV-STORE-NEXT: FloatingLiteral {{.*}} 'float' {{.*}} + +TEXTURE t; + +void main() { + uint3 i = uint3(0, 0, 0); +#if RW + t[i] = 1.0f; +#endif + float x = t[i]; + (void)x; + uint w, h; + t.GetDimensions(w, h); +} diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-wtf-containers.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-wtf-containers.cpp index 17e25d9a62703..45e40e051c18e 100644 --- a/clang/test/Analysis/Checkers/WebKit/call-args-wtf-containers.cpp +++ b/clang/test/Analysis/Checkers/WebKit/call-args-wtf-containers.cpp @@ -104,25 +104,6 @@ namespace WTF { unsigned m_size { 0 }; }; - template - class HashMap { - public: - struct Item { - T key; - S value; - }; - - template Item* find(U&) const; - template bool contains(U&) const; - template S* get(U&) const; - template S* inlineGet(U&) const; - template void add(U&) const; - template void remove(U&) const; - - private: - Item* m_table { nullptr }; - }; - template class WeakHashSet { public: diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h index de5c2d35f2408..87b495f526f27 100644 --- a/clang/test/Analysis/Checkers/WebKit/mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h @@ -11,7 +11,17 @@ template struct remove_reference { typedef T type; }; -template typename remove_reference::type&& move(T&& t); +template T&& move(T& t) { return static_cast(t); } +template T&& move(T&& t) { return t; } + +} + +#endif + +#ifndef mock_types_1103988513531 +#define mock_types_1103988513531 + +namespace std { template T exchange(T& t, U&& u) @@ -29,21 +39,6 @@ T exchange(T& t, decltype(nullptr)) return r; } -} - -#endif - -namespace WTF { - -template typename std::remove_reference::type&& move(T&& t); - -} - -#ifndef mock_types_1103988513531 -#define mock_types_1103988513531 - -namespace std { - template class unique_ptr { private: @@ -68,6 +63,186 @@ class unique_ptr { explicit operator bool() const { return !!t; } }; +namespace ranges { + +template +void for_each(IteratorType first, IteratorType last, CallbackType callback) { + for (auto it = first; !(it == last); ++it) + callback(*it); +} + +struct all_of_impl { + template + constexpr bool operator()(const Collection& collection, Predicate predicate) const { + for (auto it = collection.begin(), end = collection.end(); it != end; ++it) { + if (!predicate(*it)) + return false; + } + return true; + } +}; +inline constexpr auto all_of = all_of_impl {}; + +} + +} + +namespace WTF { + +template typename std::remove_reference::type&& move(T&& t); + +namespace Detail { + +template +class CallableWrapperBase { +public: + virtual ~CallableWrapperBase() { } + virtual Out call(In...) = 0; +}; + +template class CallableWrapper; + +template +class CallableWrapper : public CallableWrapperBase { +public: + explicit CallableWrapper(CallableType& callable) + : m_callable(callable) { } + Out call(In... in) final { return m_callable(in...); } + +private: + CallableType m_callable; +}; + +} // namespace Detail + +template class Function; + +template Function adopt(Detail::CallableWrapperBase*); + +template +class Function { +public: + using Impl = Detail::CallableWrapperBase; + + Function() = default; + + template + Function(FunctionType f) + : m_callableWrapper(new Detail::CallableWrapper(f)) { } + + Out operator()(In... in) const { return m_callableWrapper->call(in...); } + explicit operator bool() const { return !!m_callableWrapper; } + +private: + enum AdoptTag { Adopt }; + Function(Impl* impl, AdoptTag) + : m_callableWrapper(impl) + { + } + + friend Function adopt(Impl*); + + std::unique_ptr m_callableWrapper; +}; + +template Function adopt(Detail::CallableWrapperBase* impl) +{ + return Function(impl, Function::Adopt); +} + +template +class HashMap { +public: + HashMap(); + HashMap([[clang::noescape]] const Function&); + void ensure(const KeyType&, [[clang::noescape]] const Function&); + bool operator+([[clang::noescape]] const Function&) const; + static void ifAny(HashMap, [[clang::noescape]] const Function&); + + template ValueType* find(U&) const; + template bool contains(U&) const; + template ValueType* get(U&) const; + template ValueType* inlineGet(U&) const; + template void add(U&) const; + template void remove(U&) const; + +private: + ValueType* m_table { nullptr }; +}; + +class ScopeExit final { +public: + template + explicit ScopeExit(ExitFunctionParameter&& exitFunction) + : m_exitFunction(std::move(exitFunction)) { + } + + ScopeExit(ScopeExit&& other) + : m_exitFunction(std::move(other.m_exitFunction)) + , m_execute(std::move(other.m_execute)) { + } + + ~ScopeExit() { + if (m_execute) + m_exitFunction(); + } + + WTF::Function take() { + m_execute = false; + return std::move(m_exitFunction); + } + + void release() { m_execute = false; } + + ScopeExit(const ScopeExit&) = delete; + ScopeExit& operator=(const ScopeExit&) = delete; + ScopeExit& operator=(ScopeExit&&) = delete; + +private: + WTF::Function m_exitFunction; + bool m_execute { true }; +}; + +template ScopeExit makeScopeExit(ExitFunction&&); +template +ScopeExit makeScopeExit(ExitFunction&& exitFunction) +{ + return ScopeExit(std::move(exitFunction)); +} + +// Visitor adapted from http://stackoverflow.com/questions/25338795/is-there-a-name-for-this-tuple-creation-idiom + +template struct Visitor : Visitor, Visitor { + Visitor(A a, B... b) + : Visitor(a) + , Visitor(b...) + { + } + + using Visitor::operator (); + using Visitor::operator (); +}; + +template struct Visitor : A { + Visitor(A a) + : A(a) + { + } + + using A::operator(); +}; + +template Visitor makeVisitor(F... f) +{ + return Visitor(f...); +} + +void opaqueFunction(); +template void visit(Visitor&& v, Variants&&... values) +{ + opaqueFunction(); +} + }; template @@ -308,6 +483,7 @@ class CheckedObj { void incrementCheckedPtrCount() { ++m_ptrCount; } void decrementCheckedPtrCount() { --m_ptrCount; } void method(); + void constMethod() const; int trivial() { return 123; } CheckedObj* next(); diff --git a/clang/test/Analysis/Checkers/WebKit/unchecked-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/unchecked-lambda-captures.cpp new file mode 100644 index 0000000000000..611c62063db0a --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/unchecked-lambda-captures.cpp @@ -0,0 +1,533 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncheckedLambdaCapturesChecker -verify %s + +#include "mock-types.h" + +struct A { + static void b(); +}; + +CheckedObj* make_obj(); + +void someFunction(); +template void call(Callback callback) { + someFunction(); + callback(); +} +void callAsync(const WTF::Function&); + +void raw_ptr() { + CheckedObj* checked_ptr_capable = make_obj(); + auto foo1 = [checked_ptr_capable](){ + // expected-warning@-1{{Captured variable 'checked_ptr_capable' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + checked_ptr_capable->method(); + }; + auto foo2 = [&checked_ptr_capable](){ + // expected-warning@-1{{Captured variable 'checked_ptr_capable' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + checked_ptr_capable->method(); + }; + auto foo3 = [&](){ + checked_ptr_capable->method(); + // expected-warning@-1{{Implicitly captured variable 'checked_ptr_capable' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + checked_ptr_capable = nullptr; + }; + + auto foo4 = [=](){ + checked_ptr_capable->method(); + // expected-warning@-1{{Implicitly captured variable 'checked_ptr_capable' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }; + + call(foo1); + call(foo2); + call(foo3); + call(foo4); + + // Confirm that the checker respects [[clang::suppress]]. + CheckedObj* suppressed_checked_ptr_capable = nullptr; + [[clang::suppress]] auto foo5 = [suppressed_checked_ptr_capable](){}; + // no warning. + call(foo5); +} + +void references() { + CheckedObj automatic; + CheckedObj& checked_ptr_capable_ref = automatic; + auto foo1 = [checked_ptr_capable_ref](){ checked_ptr_capable_ref.constMethod(); }; + auto foo2 = [&checked_ptr_capable_ref](){ checked_ptr_capable_ref.method(); }; + // expected-warning@-1{{Captured variable 'checked_ptr_capable_ref' is a raw reference to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + auto foo3 = [&](){ checked_ptr_capable_ref.method(); }; + // expected-warning@-1{{Implicitly captured variable 'checked_ptr_capable_ref' is a raw reference to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + auto foo4 = [=](){ checked_ptr_capable_ref.constMethod(); }; + + call(foo1); + call(foo2); + call(foo3); + call(foo4); +} + +void quiet() { +// This code is not expected to trigger any warnings. + { + CheckedObj automatic; + CheckedObj &checked_ptr_capable_ref = automatic; + } + + auto foo3 = [&]() {}; + auto foo4 = [=]() {}; + + call(foo3); + call(foo4); + + CheckedObj *checked_ptr_capable = nullptr; +} + +template +void map(CheckedObj* start, [[clang::noescape]] Callback&& callback) +{ + while (start) { + callback(*start); + start = start->next(); + } +} + +template +void doubleMap(CheckedObj* start, [[clang::noescape]] Callback1&& callback1, Callback2&& callback2) +{ + while (start) { + callback1(*start); + callback2(*start); + start = start->next(); + } +} + +void noescape_lambda() { + CheckedObj* someObj = make_obj(); + CheckedObj* otherObj = make_obj(); + map(make_obj(), [&](CheckedObj& obj) { + otherObj->method(); + }); + doubleMap(make_obj(), [&](CheckedObj& obj) { + otherObj->method(); + }, [&](CheckedObj& obj) { + otherObj->method(); + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + ([&] { + someObj->method(); + })(); +} + +void lambda_capture_param(CheckedObj* obj) { + auto someLambda = [&]() { + obj->method(); + }; + someLambda(); + someLambda(); +} + +struct CheckedObjWithLambdaCapturingThis { + void incrementCheckedPtrCount() const; + void decrementCheckedPtrCount() const; + void nonTrivial(); + + void method_captures_this_safe() { + auto lambda = [&]() { + nonTrivial(); + }; + lambda(); + } + + void method_captures_this_unsafe() { + auto lambda = [&]() { + nonTrivial(); + // expected-warning@-1{{Implicitly captured variable 'this' is a raw pointer to CheckedPtr capable type 'CheckedObjWithLambdaCapturingThis' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }; + call(lambda); + } + + void method_captures_this_unsafe_capture_local_var_explicitly() { + CheckedObj* x = make_obj(); + call([this, protectedThis = CheckedPtr { this }, x]() { + // expected-warning@-1{{Captured variable 'x' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + x->method(); + }); + } + + void method_captures_this_with_other_protected_var() { + CheckedObj* x = make_obj(); + call([this, protectedX = CheckedPtr { x }]() { + // expected-warning@-1{{Captured variable 'this' is a raw pointer to CheckedPtr capable type 'CheckedObjWithLambdaCapturingThis' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + protectedX->method(); + }); + } + + void method_captures_this_unsafe_capture_local_var_explicitly_with_deref() { + CheckedObj* x = make_obj(); + call([this, protectedThis = CheckedRef { *this }, x]() { + // expected-warning@-1{{Captured variable 'x' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + x->method(); + }); + } + + void method_captures_this_unsafe_local_var_via_vardecl() { + CheckedObj* x = make_obj(); + auto lambda = [this, protectedThis = CheckedRef { *this }, x]() { + // expected-warning@-1{{Captured variable 'x' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + x->method(); + }; + call(lambda); + } + + void method_captures_this_with_guardian() { + auto lambda = [this, protectedThis = CheckedRef { *this }]() { + nonTrivial(); + }; + call(lambda); + } + + void method_captures_this_with_guardian_refptr() { + auto lambda = [this, protectedThis = CheckedPtr { &*this }]() { + nonTrivial(); + }; + call(lambda); + } + + void forEach(const WTF::Function&); + void method_captures_this_with_lambda_with_no_escape() { + auto run = [&]([[clang::noescape]] const WTF::Function& func) { + forEach(func); + }; + run([&](CheckedObj&) { + nonTrivial(); + }); + } + + static void callLambda([[clang::noescape]] const WTF::Function()>&); + void method_captures_this_in_template_method() { + CheckedObj* obj = make_obj(); + WTF::HashMap> nextMap; + nextMap.ensure(3, [&] { + return obj->next(); + }); + nextMap+[&] { + return obj->next(); + }; + WTF::HashMap>::ifAny(nextMap, [&](auto& item) -> bool { + return item->next() && obj->next(); + }); + callLambda([&]() -> CheckedPtr { + return obj->next(); + }); + WTF::HashMap> anotherMap([&] { + return obj->next(); + }); + } + + void callAsyncNoescape([[clang::noescape]] WTF::Function&&); + void method_temp_lambda(CheckedObj* obj) { + callAsyncNoescape([this, otherObj = CheckedPtr { obj }](auto& obj) { + return otherObj.get() == &obj; + }); + } + + void method_nested_lambda() { + callAsync([this, protectedThis = CheckedRef { *this }] { + callAsync([this, protectedThis = static_cast&&>(protectedThis)] { + nonTrivial(); + }); + }); + } + + void method_nested_lambda2() { + callAsync([this, protectedThis = CheckedPtr { this }] { + callAsync([this, protectedThis = std::move(*protectedThis)] { + nonTrivial(); + }); + }); + } + + void method_nested_lambda3() { + callAsync([this, protectedThis = CheckedPtr { this }] { + callAsync([this] { + // expected-warning@-1{{Captured variable 'this' is a raw pointer to CheckedPtr capable type 'CheckedObjWithLambdaCapturingThis' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + }); + }); + } + + void method_nested_lambda4() { + callAsync([this, protectedThis = CheckedPtr { this }] { + callAsync([this, protectedThis = WTF::move(*protectedThis)] { + nonTrivial(); + }); + }); + } +}; + +struct NonCheckedObjWithLambdaCapturingThis { + void nonTrivial(); + + void method_captures_this_safe() { + auto lambda = [&]() { + nonTrivial(); + }; + lambda(); + } + + void method_captures_this_unsafe() { + auto lambda = [&]() { + nonTrivial(); + }; + call(lambda); + } +}; + +void trivial_lambda() { + CheckedObj* checked_ptr_capable = make_obj(); + auto trivial_lambda = [&]() { + return checked_ptr_capable->trivial(); + }; + trivial_lambda(); +} + +bool call_lambda_var_decl() { + CheckedObj* checked_ptr_capable = make_obj(); + auto lambda1 = [&]() -> bool { + return checked_ptr_capable->next(); + }; + auto lambda2 = [=]() -> bool { + return checked_ptr_capable->next(); + }; + return lambda1() && lambda2(); +} + +void lambda_with_args(CheckedObj* obj) { + auto trivial_lambda = [&](int v) { + obj->method(); + }; + trivial_lambda(1); +} + +void callFunctionOpaque(WTF::Function&&); +void callFunction(WTF::Function&& function) { + someFunction(); + function(); +} + +void lambda_converted_to_function(CheckedObj* obj) +{ + callFunction([&]() { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + callFunctionOpaque([&]() { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); +} + +void capture_copy_in_lambda(CheckedObj& checked) { + callFunctionOpaque([checked]() mutable { + checked.method(); + }); + auto* ptr = &checked; + callFunctionOpaque([ptr]() mutable { + // expected-warning@-1{{Captured variable 'ptr' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + ptr->method(); + }); +} + +struct TemplateFunctionCallsLambda { + void ref() const; + void deref() const; + + CheckedObj* obj(); + + template + CheckedPtr method(T* t) { + auto ret = ([&]() -> CheckedPtr { + if constexpr (T::isEncodable) + return t; + return obj() ? t : nullptr; + })(); + return ret; + } +}; + +class Iterator { +public: + Iterator(void* array, unsigned long sizeOfElement, unsigned int index); + Iterator(const Iterator&); + Iterator& operator=(const Iterator&); + bool operator==(const Iterator&); + + Iterator& operator++(); + int& operator*(); + +private: + void* current { nullptr }; + unsigned long sizeOfElement { 0 }; +}; + +void ranges_for_each(CheckedObj* obj) { + int array[] = { 1, 2, 3, 4, 5 }; + std::ranges::for_each(Iterator(array, sizeof(*array), 0), Iterator(array, sizeof(*array), 5), [&](int& item) { + obj->method(); + ++item; + }); +} + +class IntCollection { +public: + int* begin(); + int* end(); + const int* begin() const; + const int* end() const; +}; + +class CheckedPtrCapableObj { +public: + void incrementCheckedPtrCount(); + void decrementCheckedPtrCount(); + + bool allOf(const IntCollection&); + bool isMatch(int); + + void call() const; + void callLambda([[clang::noescape]] const WTF::Function& callback) const; + void doSomeWork() const; +}; + +bool CheckedPtrCapableObj::allOf(const IntCollection& collection) { + return std::ranges::all_of(collection, [&](auto& number) { + return isMatch(number); + }); +} + +void CheckedPtrCapableObj::callLambda([[clang::noescape]] const WTF::Function& callback) const +{ + callback(); +} + +void CheckedPtrCapableObj::call() const +{ + auto lambda = [&] { + doSomeWork(); + }; + callLambda(lambda); +} + +void scope_exit(CheckedObj* obj) { + auto scope = WTF::makeScopeExit([&] { + obj->method(); + }); + someFunction(); + WTF::ScopeExit scope2([&] { + obj->method(); + }); + someFunction(); +} + +void doWhateverWith(WTF::ScopeExit& obj); + +void scope_exit_with_side_effect(CheckedObj* obj) { + auto scope = WTF::makeScopeExit([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + doWhateverWith(scope); +} + +void scope_exit_static(CheckedObj* obj) { + static auto scope = WTF::makeScopeExit([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); +} + +WTF::Function scope_exit_take_lambda(CheckedObj* obj) { + auto scope = WTF::makeScopeExit([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + return scope.take(); +} + +// FIXME: Ideally, we treat release() as a trivial function. +void scope_exit_release(CheckedObj* obj) { + auto scope = WTF::makeScopeExit([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + scope.release(); +} + +void make_visitor(CheckedObj* obj) { + auto visitor = WTF::makeVisitor([&] { + obj->method(); + }); +} + +void use_visitor(CheckedObj* obj) { + auto visitor = WTF::makeVisitor([&] { + obj->method(); + }); + WTF::visit(visitor, obj); +} + +template +void bad_visit(Visitor&, ObjectType*) { + someFunction(); +} + +void static_visitor(CheckedObj* obj) { + static auto visitor = WTF::makeVisitor([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); +} + +void make_visitor_with_multiple_lambdas(CheckedObj* obj) { + auto* otherObj = make_obj(); + auto visitor = WTF::makeVisitor([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }, [&] { + otherObj->method(); + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + bad_visit(visitor, obj); +} + +void bad_use_visitor(CheckedObj* obj) { + auto visitor = WTF::makeVisitor([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + bad_visit(visitor, obj); +} + +class LambdaInConstructorDestructor { +public: + LambdaInConstructorDestructor() { + call([this]() { + // expected-warning@-1{{Captured variable 'this' is a raw pointer to CheckedPtr capable type 'LambdaInConstructorDestructor' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + doWork(); + }); + } + + ~LambdaInConstructorDestructor() { + call([this]() { + // expected-warning@-1{{Captured variable 'this' is a raw pointer to CheckedPtr capable type 'LambdaInConstructorDestructor' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + doWork(); + }); + } + + void incrementCheckedPtrCount() const; + void decrementCheckedPtrCount() const; + + void doWork(); +}; diff --git a/clang/test/Analysis/Checkers/WebKit/unchecked-members-objc.mm b/clang/test/Analysis/Checkers/WebKit/unchecked-members-objc.mm index a9a9a367fb9f4..9ab9460630ec4 100644 --- a/clang/test/Analysis/Checkers/WebKit/unchecked-members-objc.mm +++ b/clang/test/Analysis/Checkers/WebKit/unchecked-members-objc.mm @@ -14,7 +14,7 @@ - (void)release; @interface SomeObjC : NSObject { CheckedObj* _unchecked1; -// expected-warning@-1{{Instance variable '_unchecked1' in 'SomeObjC' is a raw pointer to CheckedPtr capable type 'CheckedObj'}} +// expected-warning@-1{{Instance variable '_unchecked1' (of 'SomeObjC') is a raw pointer to CheckedPtr-capable type 'CheckedObj'}} CheckedPtr _counted1; [[clang::suppress]] CheckedObj* _unchecked2; } @@ -23,7 +23,7 @@ - (void)doWork; @implementation SomeObjC { CheckedObj* _unchecked3; -// expected-warning@-1{{Instance variable '_unchecked3' in 'SomeObjC' is a raw pointer to CheckedPtr capable type 'CheckedObj'}} +// expected-warning@-1{{Instance variable '_unchecked3' (of 'SomeObjC') is a raw pointer to CheckedPtr-capable type 'CheckedObj'}} CheckedPtr _counted2; [[clang::suppress]] CheckedObj* _unchecked4; } diff --git a/clang/test/Analysis/Checkers/WebKit/unchecked-members.cpp b/clang/test/Analysis/Checkers/WebKit/unchecked-members.cpp index 3fe15d88ff312..48f9f2119de2b 100644 --- a/clang/test/Analysis/Checkers/WebKit/unchecked-members.cpp +++ b/clang/test/Analysis/Checkers/WebKit/unchecked-members.cpp @@ -7,9 +7,9 @@ namespace members { struct Foo { private: CheckedObj* a = nullptr; -// expected-warning@-1{{Member variable 'a' in 'members::Foo' is a raw pointer to CheckedPtr capable type 'CheckedObj'}} +// expected-warning@-1{{Member variable 'a' (of 'members::Foo') is a raw pointer to CheckedPtr-capable type 'CheckedObj'}} CheckedObj& b; -// expected-warning@-1{{Member variable 'b' in 'members::Foo' is a reference to CheckedPtr capable type 'CheckedObj'}} +// expected-warning@-1{{Member variable 'b' (of 'members::Foo') is a reference to CheckedPtr-capable type 'CheckedObj'}} [[clang::suppress]] CheckedObj* a_suppressed = nullptr; @@ -27,7 +27,7 @@ namespace members { template struct FooTmpl { S* e; -// expected-warning@-1{{Member variable 'e' in 'members::FooTmpl' is a raw pointer to CheckedPtr capable type 'CheckedObj'}} +// expected-warning@-1{{Member variable 'e' (of 'members::FooTmpl') is a raw pointer to CheckedPtr-capable type 'CheckedObj'}} }; void forceTmplToInstantiate(FooTmpl) { } @@ -38,7 +38,7 @@ namespace unions { union Foo { CheckedObj* a; - // expected-warning@-1{{Member variable 'a' in 'unions::Foo' is a raw pointer to CheckedPtr capable type 'CheckedObj'}} + // expected-warning@-1{{Member variable 'a' (of 'unions::Foo') is a raw pointer to CheckedPtr-capable type 'CheckedObj'}} CheckedPtr c; CheckedRef d; }; @@ -46,7 +46,7 @@ namespace unions { template union FooTmpl { T* a; - // expected-warning@-1{{Member variable 'a' in 'unions::FooTmpl' is a raw pointer to CheckedPtr capable type 'CheckedObj'}} + // expected-warning@-1{{Member variable 'a' (of 'unions::FooTmpl') is a raw pointer to CheckedPtr-capable type 'CheckedObj'}} }; void forceTmplToInstantiate(FooTmpl) { } @@ -66,13 +66,13 @@ namespace ptr_to_ptr_to_checked_ptr_capable { struct List { CheckedObj** elements; - // expected-warning@-1{{Member variable 'elements' in 'ptr_to_ptr_to_checked_ptr_capable::List' contains a raw pointer to CheckedPtr capable type 'CheckedObj'}} + // expected-warning@-1{{Member variable 'elements' (of 'ptr_to_ptr_to_checked_ptr_capable::List') contains a raw pointer to CheckedPtr-capable type 'CheckedObj'}} }; template struct TemplateList { T** elements; - // expected-warning@-1{{Member variable 'elements' in 'ptr_to_ptr_to_checked_ptr_capable::TemplateList' contains a raw pointer to CheckedPtr capable type 'CheckedObj'}} + // expected-warning@-1{{Member variable 'elements' (of 'ptr_to_ptr_to_checked_ptr_capable::TemplateList') contains a raw pointer to CheckedPtr-capable type 'CheckedObj'}} }; TemplateList list; diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp index 0c10c69a97eda..1afbd0df93f18 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp @@ -28,9 +28,9 @@ struct Obj { void foo(Foo foo) { bar([this](auto baz) { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'Obj' [webkit.UncountedLambdaCapturesChecker]}} bar([this, foo = *baz, foo2 = !baz](auto&&) { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'Obj' [webkit.UncountedLambdaCapturesChecker]}} someFunction(); }); }); diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp index 43834f5414f41..fc8230838c5cb 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp @@ -2,186 +2,6 @@ #include "mock-types.h" -namespace std { - -template -T&& move(T& t) { - return static_cast(t); -} - -namespace ranges { - -template -void for_each(IteratorType first, IteratorType last, CallbackType callback) { - for (auto it = first; !(it == last); ++it) - callback(*it); -} - -struct all_of_impl { - template - constexpr bool operator()(const Collection& collection, Predicate predicate) const { - for (auto it = collection.begin(); it != collection.end(); ++it) { - if (!predicate(*it)) - return false; - } - return true; - } -}; -inline constexpr auto all_of = all_of_impl {}; - -} - -} - -namespace WTF { - -namespace Detail { - -template -class CallableWrapperBase { -public: - virtual ~CallableWrapperBase() { } - virtual Out call(In...) = 0; -}; - -template class CallableWrapper; - -template -class CallableWrapper : public CallableWrapperBase { -public: - explicit CallableWrapper(CallableType& callable) - : m_callable(callable) { } - Out call(In... in) final { return m_callable(in...); } - -private: - CallableType m_callable; -}; - -} // namespace Detail - -template class Function; - -template Function adopt(Detail::CallableWrapperBase*); - -template -class Function { -public: - using Impl = Detail::CallableWrapperBase; - - Function() = default; - - template - Function(FunctionType f) - : m_callableWrapper(new Detail::CallableWrapper(f)) { } - - Out operator()(In... in) const { return m_callableWrapper->call(in...); } - explicit operator bool() const { return !!m_callableWrapper; } - -private: - enum AdoptTag { Adopt }; - Function(Impl* impl, AdoptTag) - : m_callableWrapper(impl) - { - } - - friend Function adopt(Impl*); - - std::unique_ptr m_callableWrapper; -}; - -template Function adopt(Detail::CallableWrapperBase* impl) -{ - return Function(impl, Function::Adopt); -} - -template -class HashMap { -public: - HashMap(); - HashMap([[clang::noescape]] const Function&); - void ensure(const KeyType&, [[clang::noescape]] const Function&); - bool operator+([[clang::noescape]] const Function&) const; - static void ifAny(HashMap, [[clang::noescape]] const Function&); - -private: - ValueType* m_table { nullptr }; -}; - -class ScopeExit final { -public: - template - explicit ScopeExit(ExitFunctionParameter&& exitFunction) - : m_exitFunction(std::move(exitFunction)) { - } - - ScopeExit(ScopeExit&& other) - : m_exitFunction(std::move(other.m_exitFunction)) - , m_execute(std::move(other.m_execute)) { - } - - ~ScopeExit() { - if (m_execute) - m_exitFunction(); - } - - WTF::Function take() { - m_execute = false; - return std::move(m_exitFunction); - } - - void release() { m_execute = false; } - - ScopeExit(const ScopeExit&) = delete; - ScopeExit& operator=(const ScopeExit&) = delete; - ScopeExit& operator=(ScopeExit&&) = delete; - -private: - WTF::Function m_exitFunction; - bool m_execute { true }; -}; - -template ScopeExit makeScopeExit(ExitFunction&&); -template -ScopeExit makeScopeExit(ExitFunction&& exitFunction) -{ - return ScopeExit(std::move(exitFunction)); -} - -// Visitor adapted from http://stackoverflow.com/questions/25338795/is-there-a-name-for-this-tuple-creation-idiom - -template struct Visitor : Visitor, Visitor { - Visitor(A a, B... b) - : Visitor(a) - , Visitor(b...) - { - } - - using Visitor::operator (); - using Visitor::operator (); -}; - -template struct Visitor : A { - Visitor(A a) - : A(a) - { - } - - using A::operator(); -}; - -template Visitor makeVisitor(F... f) -{ - return Visitor(f...); -} - -void opaqueFunction(); -template void visit(Visitor&& v, Variants&&... values) -{ - opaqueFunction(); -} - -} // namespace WTF - struct A { static void b(); }; @@ -198,22 +18,22 @@ void callAsync(const WTF::Function&); void raw_ptr() { RefCountable* ref_countable = make_obj(); auto foo1 = [ref_countable](){ - // expected-warning@-1{{Captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'ref_countable' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} ref_countable->method(); }; auto foo2 = [&ref_countable](){ - // expected-warning@-1{{Captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'ref_countable' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} ref_countable->method(); }; auto foo3 = [&](){ ref_countable->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'ref_countable' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} ref_countable = nullptr; }; auto foo4 = [=](){ ref_countable->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'ref_countable' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }; call(foo1); @@ -233,9 +53,9 @@ void references() { RefCountable& ref_countable_ref = automatic; auto foo1 = [ref_countable_ref](){ ref_countable_ref.constMethod(); }; auto foo2 = [&ref_countable_ref](){ ref_countable_ref.method(); }; - // expected-warning@-1{{Captured reference 'ref_countable_ref' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'ref_countable_ref' is a raw reference to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} auto foo3 = [&](){ ref_countable_ref.method(); }; - // expected-warning@-1{{Implicitly captured reference 'ref_countable_ref' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'ref_countable_ref' is a raw reference to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} auto foo4 = [=](){ ref_countable_ref.constMethod(); }; call(foo1); @@ -289,7 +109,7 @@ void noescape_lambda() { otherObj->method(); }, [&](RefCountable& obj) { otherObj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'otherObj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); ([&] { someObj->method(); @@ -319,7 +139,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_unsafe() { auto lambda = [&]() { nonTrivial(); - // expected-warning@-1{{Implicitly captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'this' is a raw pointer to ref-countable type 'RefCountableWithLambdaCapturingThis' [webkit.UncountedLambdaCapturesChecker]}} }; call(lambda); } @@ -327,7 +147,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_unsafe_capture_local_var_explicitly() { RefCountable* x = make_obj(); call([this, protectedThis = RefPtr { this }, x]() { - // expected-warning@-1{{Captured raw-pointer 'x' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'x' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); x->method(); }); @@ -336,7 +156,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_with_other_protected_var() { RefCountable* x = make_obj(); call([this, protectedX = RefPtr { x }]() { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'RefCountableWithLambdaCapturingThis' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); protectedX->method(); }); @@ -345,7 +165,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_unsafe_capture_local_var_explicitly_with_deref() { RefCountable* x = make_obj(); call([this, protectedThis = Ref { *this }, x]() { - // expected-warning@-1{{Captured raw-pointer 'x' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'x' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); x->method(); }); @@ -354,7 +174,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_unsafe_local_var_via_vardecl() { RefCountable* x = make_obj(); auto lambda = [this, protectedThis = Ref { *this }, x]() { - // expected-warning@-1{{Captured raw-pointer 'x' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'x' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); x->method(); }; @@ -432,7 +252,7 @@ struct RefCountableWithLambdaCapturingThis { void method_nested_lambda3() { callAsync([this, protectedThis = RefPtr { this }] { callAsync([this] { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'RefCountableWithLambdaCapturingThis' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); }); }); @@ -501,22 +321,11 @@ void lambda_converted_to_function(RefCountable* obj) { callFunction([&]() { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); callFunctionOpaque([&]() { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} - }); -} - -void capture_copy_in_lambda(CheckedObj& checked) { - callFunctionOpaque([checked]() mutable { - checked.method(); - }); - auto* ptr = &checked; - callFunctionOpaque([ptr]() mutable { - // expected-warning@-1{{Captured raw-pointer 'ptr' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} - ptr->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); } @@ -616,7 +425,7 @@ void doWhateverWith(WTF::ScopeExit& obj); void scope_exit_with_side_effect(RefCountable* obj) { auto scope = WTF::makeScopeExit([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); doWhateverWith(scope); } @@ -624,14 +433,14 @@ void scope_exit_with_side_effect(RefCountable* obj) { void scope_exit_static(RefCountable* obj) { static auto scope = WTF::makeScopeExit([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); } WTF::Function scope_exit_take_lambda(RefCountable* obj) { auto scope = WTF::makeScopeExit([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); return scope.take(); } @@ -640,7 +449,7 @@ WTF::Function scope_exit_take_lambda(RefCountable* obj) { void scope_exit_release(RefCountable* obj) { auto scope = WTF::makeScopeExit([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); scope.release(); } @@ -666,7 +475,7 @@ void bad_visit(Visitor&, ObjectType*) { void static_visitor(RefCountable* obj) { static auto visitor = WTF::makeVisitor([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); } @@ -674,10 +483,10 @@ void make_visitor_with_multiple_lambdas(RefCountable* obj) { auto* otherObj = make_obj(); auto visitor = WTF::makeVisitor([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }, [&] { otherObj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'otherObj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); bad_visit(visitor, obj); } @@ -685,7 +494,7 @@ void make_visitor_with_multiple_lambdas(RefCountable* obj) { void bad_use_visitor(RefCountable* obj) { auto visitor = WTF::makeVisitor([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); bad_visit(visitor, obj); } @@ -694,14 +503,14 @@ class LambdaInConstructorDestructor { public: LambdaInConstructorDestructor() { call([this]() { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'LambdaInConstructorDestructor' [webkit.UncountedLambdaCapturesChecker]}} doWork(); }); } ~LambdaInConstructorDestructor() { call([this]() { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'LambdaInConstructorDestructor' [webkit.UncountedLambdaCapturesChecker]}} doWork(); }); } diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-members-objc.mm b/clang/test/Analysis/Checkers/WebKit/uncounted-members-objc.mm index 83b08a6841d26..2e0959c96cade 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-members-objc.mm +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-members-objc.mm @@ -14,7 +14,7 @@ - (void)release; @interface SomeObjC : NSObject { RefCountable* _uncounted1; -// expected-warning@-1{{Instance variable '_uncounted1' in 'SomeObjC' is a raw pointer to ref-countable type 'RefCountable'}} +// expected-warning@-1{{Instance variable '_uncounted1' (of 'SomeObjC') is a raw pointer to RefPtr-capable type 'RefCountable'}} RefPtr _counted1; [[clang::suppress]] RefCountable* _uncounted2; } @@ -23,7 +23,7 @@ - (void)doWork; @implementation SomeObjC { RefCountable* _uncounted3; -// expected-warning@-1{{Instance variable '_uncounted3' in 'SomeObjC' is a raw pointer to ref-countable type 'RefCountable'}} +// expected-warning@-1{{Instance variable '_uncounted3' (of 'SomeObjC') is a raw pointer to RefPtr-capable type 'RefCountable'}} RefPtr _counted2; [[clang::suppress]] RefCountable* _uncounted4; } diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-members-ref-deref-on-diff-classes.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-members-ref-deref-on-diff-classes.cpp index 4198b2388fed8..2e69998db5974 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-members-ref-deref-on-diff-classes.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-members-ref-deref-on-diff-classes.cpp @@ -19,5 +19,5 @@ class TreeNode : public RefCounted { private: TreeNode* m_parent; -// expected-warning@-1{{Member variable 'm_parent' in 'TreeNode' is a raw pointer to ref-countable type 'TreeNode'}} +// expected-warning@-1{{Member variable 'm_parent' (of 'TreeNode') is a raw pointer to RefPtr-capable type 'TreeNode'}} }; diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-members.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-members.cpp index b8c443cda4f8e..4da8818f0fc9a 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-members.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-members.cpp @@ -7,7 +7,7 @@ namespace members { struct Foo { private: RefCountable* a = nullptr; -// expected-warning@-1{{Member variable 'a' in 'members::Foo' is a raw pointer to ref-countable type 'RefCountable'}} +// expected-warning@-1{{Member variable 'a' (of 'members::Foo') is a raw pointer to RefPtr-capable type 'RefCountable'}} [[clang::suppress]] RefCountable* a_suppressed = nullptr; @@ -18,14 +18,14 @@ namespace members { public: RefCountable silenceWarningAboutInit; RefCountable& c = silenceWarningAboutInit; -// expected-warning@-1{{Member variable 'c' in 'members::Foo' is a reference to ref-countable type 'RefCountable'}} +// expected-warning@-1{{Member variable 'c' (of 'members::Foo') is a reference to RefPtr-capable type 'RefCountable'}} Ref d; }; template struct FooTmpl { T* a; -// expected-warning@-1{{Member variable 'a' in 'members::FooTmpl' is a raw pointer to ref-countable type 'RefCountable'}} +// expected-warning@-1{{Member variable 'a' (of 'members::FooTmpl') is a raw pointer to RefPtr-capable type 'RefCountable'}} }; void forceTmplToInstantiate(FooTmpl) {} @@ -39,7 +39,7 @@ namespace members { namespace unions { union Foo { RefCountable* a; - // expected-warning@-1{{Member variable 'a' in 'unions::Foo' is a raw pointer to ref-countable type 'RefCountable'}} + // expected-warning@-1{{Member variable 'a' (of 'unions::Foo') is a raw pointer to RefPtr-capable type 'RefCountable'}} RefPtr b; Ref c; }; @@ -47,7 +47,7 @@ namespace unions { template union FooTmpl { T* a; - // expected-warning@-1{{Member variable 'a' in 'unions::FooTmpl' is a raw pointer to ref-countable type 'RefCountable'}} + // expected-warning@-1{{Member variable 'a' (of 'unions::FooTmpl') is a raw pointer to RefPtr-capable type 'RefCountable'}} }; void forceTmplToInstantiate(FooTmpl) {} @@ -84,13 +84,13 @@ namespace ptr_to_ptr_to_ref_counted { struct List { RefCountable** elements; - // expected-warning@-1{{Member variable 'elements' in 'ptr_to_ptr_to_ref_counted::List' contains a raw pointer to ref-countable type 'RefCountable'}} + // expected-warning@-1{{Member variable 'elements' (of 'ptr_to_ptr_to_ref_counted::List') contains a raw pointer to RefPtr-capable type 'RefCountable'}} }; template struct TemplateList { T** elements; - // expected-warning@-1{{Member variable 'elements' in 'ptr_to_ptr_to_ref_counted::TemplateList' contains a raw pointer to ref-countable type 'RefCountable'}} + // expected-warning@-1{{Member variable 'elements' (of 'ptr_to_ptr_to_ref_counted::TemplateList') contains a raw pointer to RefPtr-capable type 'RefCountable'}} }; TemplateList list; diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures-arc.mm index 4e024dea7037a..15337cb011267 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures-arc.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures-arc.mm @@ -139,21 +139,21 @@ void raw_ptr() { auto cf = make_cf(); auto bar1 = [cf](){ - // expected-warning@-1{{Captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); }; auto bar2 = [&cf](){ - // expected-warning@-1{{Captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); }; auto bar3 = [&](){ CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} cf = nullptr; }; auto bar4 = [=](){ CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; auto os = make_os(); @@ -255,7 +255,7 @@ void noescape_lambda() { CFArrayAppendValue(someCF, nullptr); }, [&](CFIndex count) { CFArrayAppendValue(someCF, nullptr); - // expected-warning@-1{{Implicitly captured reference 'someCF' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'someCF' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); dispatch_queue_t someOS = make_os(); @@ -277,13 +277,13 @@ void lambda_converted_to_function(SomeObj* obj, CFMutableArrayRef cf, dispatch_q callFunction([&]() { [obj doWork]; CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); }); callFunctionOpaque([&]() { [obj doWork]; CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); }); } diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures.mm b/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures.mm index 76a1da7707a2a..aad6cd245f1bd 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures.mm @@ -1,111 +1,8 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UnretainedLambdaCapturesChecker -verify %s +#include "mock-types.h" #include "objc-mock-types.h" -namespace std { - -template -class unique_ptr { -private: - T *t; - -public: - unique_ptr() : t(nullptr) { } - unique_ptr(T *t) : t(t) { } - ~unique_ptr() { - if (t) - delete t; - } - template unique_ptr(unique_ptr&& u) - : t(u.t) - { - u.t = nullptr; - } - T *get() const { return t; } - T *operator->() const { return t; } - T &operator*() const { return *t; } - unique_ptr &operator=(T *) { return *this; } - explicit operator bool() const { return !!t; } -}; - -}; - -namespace WTF { - -namespace Detail { - -template -class CallableWrapperBase { -public: - virtual ~CallableWrapperBase() { } - virtual Out call(In...) = 0; -}; - -template class CallableWrapper; - -template -class CallableWrapper : public CallableWrapperBase { -public: - explicit CallableWrapper(CallableType& callable) - : m_callable(callable) { } - Out call(In... in) final { return m_callable(in...); } - -private: - CallableType m_callable; -}; - -} // namespace Detail - -template class Function; - -template Function adopt(Detail::CallableWrapperBase*); - -template -class Function { -public: - using Impl = Detail::CallableWrapperBase; - - Function() = default; - - template - Function(FunctionType f) - : m_callableWrapper(new Detail::CallableWrapper(f)) { } - - Out operator()(In... in) const { return m_callableWrapper->call(in...); } - explicit operator bool() const { return !!m_callableWrapper; } - -private: - enum AdoptTag { Adopt }; - Function(Impl* impl, AdoptTag) - : m_callableWrapper(impl) - { - } - - friend Function adopt(Impl*); - - std::unique_ptr m_callableWrapper; -}; - -template Function adopt(Detail::CallableWrapperBase* impl) -{ - return Function(impl, Function::Adopt); -} - -template -class HashMap { -public: - HashMap(); - HashMap([[clang::noescape]] const Function&); - void ensure(const KeyType&, [[clang::noescape]] const Function&); - bool operator+([[clang::noescape]] const Function&) const; - static void ifAny(HashMap, [[clang::noescape]] const Function&); - -private: - ValueType* m_table { nullptr }; -}; - -} // namespace WTF - struct A { static void b(); }; @@ -124,61 +21,61 @@ explicit CallableWrapper(CallableType& callable) void raw_ptr() { SomeObj* obj = make_obj(); auto foo1 = [obj](){ - // expected-warning@-1{{Captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} [obj doWork]; }; call(foo1); auto foo2 = [&obj](){ - // expected-warning@-1{{Captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} [obj doWork]; }; auto foo3 = [&](){ [obj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} obj = nullptr; }; auto foo4 = [=](){ [obj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; auto cf = make_cf(); auto bar1 = [cf](){ - // expected-warning@-1{{Captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); }; auto bar2 = [&cf](){ - // expected-warning@-1{{Captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); }; auto bar3 = [&](){ CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} cf = nullptr; }; auto bar4 = [=](){ CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; auto os = make_os(); auto baz1 = [os](){ - // expected-warning@-1{{Captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); }; auto baz2 = [&os](){ - // expected-warning@-1{{Captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); }; auto baz3 = [&](){ dispatch_queue_get_label(os); - // expected-warning@-1{{Implicitly captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} os = nullptr; }; auto baz4 = [=](){ dispatch_queue_get_label(os); - // expected-warning@-1{{Implicitly captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; call(foo1); @@ -219,6 +116,7 @@ void raw_ptr() { }; // no warning. call(baz5); + } void quiet() { @@ -279,7 +177,7 @@ void noescape_lambda() { [otherObj doWork]; }, [&](SomeObj *obj) { [otherObj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'otherObj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); ([&] { [someObj doWork]; @@ -290,7 +188,7 @@ void noescape_lambda() { CFArrayAppendValue(someCF, nullptr); }, [&](CFIndex count) { CFArrayAppendValue(someCF, nullptr); - // expected-warning@-1{{Implicitly captured reference 'someCF' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'someCF' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); dispatch_queue_t someOS = make_os(); @@ -298,7 +196,7 @@ void noescape_lambda() { dispatch_queue_get_label(someOS); }, [&](const char* label) { dispatch_queue_get_label(someOS); - // expected-warning@-1{{Implicitly captured reference 'someOS' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'someOS' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); } @@ -312,19 +210,19 @@ void lambda_converted_to_function(SomeObj* obj, CFMutableArrayRef cf, dispatch_q { callFunction([&]() { [obj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); - // expected-warning@-1{{Implicitly captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); callFunctionOpaque([&]() { [obj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); - // expected-warning@-1{{Implicitly captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); } @@ -340,12 +238,12 @@ -(void)run; @implementation ObjWithSelf -(void)doWork { auto doWork = [&] { - // expected-warning@-1{{Implicitly captured raw-pointer 'self' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'self' is a raw pointer to retainable type 'ObjWithSelf' [alpha.webkit.UnretainedLambdaCapturesChecker]}} someFunction(); [delegate doWork]; }; auto doMoreWork = [=] { - // expected-warning@-1{{Implicitly captured raw-pointer 'self' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'self' is a raw pointer to retainable type 'ObjWithSelf' [alpha.webkit.UnretainedLambdaCapturesChecker]}} someFunction(); [delegate doWork]; }; @@ -357,7 +255,7 @@ -(void)doWork { auto doAdditionalWork = [&] { someFunction(); dispatch_queue_get_label(queuePtr); - // expected-warning@-1{{Implicitly captured raw-pointer 'queuePtr' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'queuePtr' is a retainable type 'OS_dispatch_queue' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; callFunctionOpaque(doWork); callFunctionOpaque(doMoreWork); diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm index 4eef372d26480..ca70b75fc7557 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-members-arc.mm @@ -19,7 +19,7 @@ RetainPtr d; CFMutableArrayRef e = nullptr; -// expected-warning@-1{{Member variable 'e' in 'members::Foo' is a retainable type 'CFMutableArrayRef'}} +// expected-warning@-1{{Member variable 'e' (of 'members::Foo') is a RetainPtr-capable type 'CFMutableArrayRef'}} dispatch_queue_t f = nullptr; }; @@ -27,7 +27,7 @@ union FooUnion { SomeObj* a; CFMutableArrayRef b; - // expected-warning@-1{{Member variable 'b' in 'members::FooUnion' is a retainable type 'CFMutableArrayRef'}} + // expected-warning@-1{{Member variable 'b' (of 'members::FooUnion') is a RetainPtr-capable type 'CFMutableArrayRef'}} dispatch_queue_t c; }; @@ -35,7 +35,7 @@ struct FooTmpl { T* x; S y; -// expected-warning@-1{{Member variable 'y' in 'members::FooTmpl *>' is a raw pointer to retainable type}} +// expected-warning@-1{{Member variable 'y' (of 'members::FooTmpl *>') is a raw pointer to RetainPtr-capable type}} R z; }; @@ -52,14 +52,14 @@ void forceTmplToInstantiate(FooTmpl struct TemplateList { T* elements1; S* elements2; - // expected-warning@-1{{Member variable 'elements2' in 'ptr_to_ptr_to_retained::TemplateList *>' contains a raw pointer to retainable type '__CFArray'}} + // expected-warning@-1{{Member variable 'elements2' (of 'ptr_to_ptr_to_retained::TemplateList *>') contains a raw pointer to RetainPtr-capable type '__CFArray'}} R* elements3; }; TemplateList list; @@ -75,14 +75,14 @@ void forceTmplToInstantiate(FooTmpl d; OSObjectPtr d2; CFMutableArrayRef e = nullptr; -// expected-warning@-1{{Member variable 'e' in 'members::Foo' is a retainable type 'CFMutableArrayRef'}} +// expected-warning@-1{{Member variable 'e' (of 'members::Foo') is a RetainPtr-capable type 'CFMutableArrayRef'}} }; template struct FooTmpl { T* a; -// expected-warning@-1{{Member variable 'a' in 'members::FooTmpl *>' is a raw pointer to retainable type}} +// expected-warning@-1{{Member variable 'a' (of 'members::FooTmpl *>') is a raw pointer to RetainPtr-capable type}} S b; -// expected-warning@-1{{Member variable 'b' in 'members::FooTmpl *>' is a raw pointer to retainable type}} +// expected-warning@-1{{Member variable 'b' (of 'members::FooTmpl *>') is a raw pointer to RetainPtr-capable type}} R c; -// expected-warning@-1{{Member variable 'c' in 'members::FooTmpl *>' is a raw pointer to retainable type}} +// expected-warning@-1{{Member variable 'c' (of 'members::FooTmpl *>') is a raw pointer to RetainPtr-capable type}} }; void forceTmplToInstantiate(FooTmpl) {} @@ -58,18 +58,18 @@ void forceTmplToInstantiate(FooTmpl b; CFMutableArrayRef c; - // expected-warning@-1{{Member variable 'c' in 'unions::Foo' is a retainable type 'CFMutableArrayRef'}} + // expected-warning@-1{{Member variable 'c' (of 'unions::Foo') is a RetainPtr-capable type 'CFMutableArrayRef'}} dispatch_queue_t d; - // expected-warning@-1{{Member variable 'd' in 'unions::Foo' is a retainable type 'dispatch_queue_t'}} + // expected-warning@-1{{Member variable 'd' (of 'unions::Foo') is a RetainPtr-capable type 'dispatch_queue_t'}} }; template union FooTempl { T* a; - // expected-warning@-1{{Member variable 'a' in 'unions::FooTempl' is a raw pointer to retainable type 'SomeObj'}} + // expected-warning@-1{{Member variable 'a' (of 'unions::FooTempl') is a raw pointer to RetainPtr-capable type 'SomeObj'}} }; void forceTmplToInstantiate(FooTempl) {} @@ -79,21 +79,21 @@ void forceTmplToInstantiate(FooTempl) {} struct List { SomeObj** elements1; - // expected-warning@-1{{Member variable 'elements1' in 'ptr_to_ptr_to_retained::List' contains a raw pointer to retainable type 'SomeObj'}} + // expected-warning@-1{{Member variable 'elements1' (of 'ptr_to_ptr_to_retained::List') contains a raw pointer to RetainPtr-capable type 'SomeObj'}} CFMutableArrayRef* elements2; - // expected-warning@-1{{Member variable 'elements2' in 'ptr_to_ptr_to_retained::List' contains a retainable type 'CFMutableArrayRef'}} + // expected-warning@-1{{Member variable 'elements2' (of 'ptr_to_ptr_to_retained::List') contains a RetainPtr-capable type 'CFMutableArrayRef'}} dispatch_queue_t* elements3; - // expected-warning@-1{{Member variable 'elements3' in 'ptr_to_ptr_to_retained::List' contains a retainable type 'dispatch_queue_t'}} + // expected-warning@-1{{Member variable 'elements3' (of 'ptr_to_ptr_to_retained::List') contains a RetainPtr-capable type 'dispatch_queue_t'}} }; template struct TemplateList { T** elements1; - // expected-warning@-1{{Member variable 'elements1' in 'ptr_to_ptr_to_retained::TemplateList *>' contains a raw pointer to retainable type 'SomeObj'}} + // expected-warning@-1{{Member variable 'elements1' (of 'ptr_to_ptr_to_retained::TemplateList *>') contains a raw pointer to RetainPtr-capable type 'SomeObj'}} S* elements2; - // expected-warning@-1{{Member variable 'elements2' in 'ptr_to_ptr_to_retained::TemplateList *>' contains a raw pointer to retainable type '__CFArray'}} + // expected-warning@-1{{Member variable 'elements2' (of 'ptr_to_ptr_to_retained::TemplateList *>') contains a raw pointer to RetainPtr-capable type '__CFArray'}} R* elements3; - // expected-warning@-1{{Member variable 'elements3' in 'ptr_to_ptr_to_retained::TemplateList *>' contains a raw pointer to retainable type 'NSObject'}} + // expected-warning@-1{{Member variable 'elements3' (of 'ptr_to_ptr_to_retained::TemplateList *>') contains a raw pointer to RetainPtr-capable type 'NSObject'}} }; TemplateList list; @@ -106,11 +106,11 @@ void forceTmplToInstantiate(FooTempl) {} @interface AnotherObject : NSObject { NSString *ns_string; - // expected-warning@-1{{Instance variable 'ns_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'}} + // expected-warning@-1{{Instance variable 'ns_string' (of 'AnotherObject') is a raw pointer to RetainPtr-capable type 'NSString'}} CFStringRef cf_string; - // expected-warning@-1{{Instance variable 'cf_string' in 'AnotherObject' is a retainable type 'CFStringRef'}} + // expected-warning@-1{{Instance variable 'cf_string' (of 'AnotherObject') is a RetainPtr-capable type 'CFStringRef'}} dispatch_queue_t dispatch; - // expected-warning@-1{{Instance variable 'dispatch' in 'AnotherObject' is a retainable type 'dispatch_queue_t'}} + // expected-warning@-1{{Instance variable 'dispatch' (of 'AnotherObject') is a RetainPtr-capable type 'dispatch_queue_t'}} } @property(nonatomic, readonly, strong) NSString *prop_string; @property(nonatomic, readonly) NSString *prop_safe; @@ -124,11 +124,11 @@ - (NSString *)prop_safe { @interface DerivedObject : AnotherObject { NSNumber *ns_number; - // expected-warning@-1{{Instance variable 'ns_number' in 'DerivedObject' is a raw pointer to retainable type 'NSNumber'}} + // expected-warning@-1{{Instance variable 'ns_number' (of 'DerivedObject') is a raw pointer to RetainPtr-capable type 'NSNumber'}} CGImageRef cg_image; - // expected-warning@-1{{Instance variable 'cg_image' in 'DerivedObject' is a retainable type 'CGImageRef'}} + // expected-warning@-1{{Instance variable 'cg_image' (of 'DerivedObject') is a RetainPtr-capable type 'CGImageRef'}} dispatch_queue_t os_dispatch; - // expected-warning@-1{{Instance variable 'os_dispatch' in 'DerivedObject' is a retainable type 'dispatch_queue_t'}} + // expected-warning@-1{{Instance variable 'os_dispatch' (of 'DerivedObject') is a RetainPtr-capable type 'dispatch_queue_t'}} } @property(nonatomic, strong) NSNumber *prop_number; @property(nonatomic, readonly) NSString *prop_string; @@ -152,13 +152,13 @@ @interface InterfaceOnlyObject2 : NSObject @property(nonatomic, strong) NSString *prop_string1; @property(nonatomic, assign) NSString *prop_string2; @property(nonatomic, unsafe_unretained) NSString *prop_string3; -// expected-warning@-1{{Property 'prop_string3' in 'DerivedObject2' is a raw pointer to retainable type 'NSString'}} +// expected-warning@-1{{Property 'prop_string3' (of 'DerivedObject2') is a raw pointer to RetainPtr-capable type 'NSString'}} @property(nonatomic, readonly) NSString *prop_string4; @end @interface DerivedObject2 : InterfaceOnlyObject2 @property(nonatomic, readonly) NSString *prop_string5; -// expected-warning@-1{{Property 'prop_string5' in 'DerivedObject2' is a raw pointer to retainable type 'NSString'}} +// expected-warning@-1{{Property 'prop_string5' (of 'DerivedObject2') is a raw pointer to RetainPtr-capable type 'NSString'}} @end @implementation DerivedObject2 @@ -168,18 +168,18 @@ @implementation DerivedObject2 NS_REQUIRES_PROPERTY_DEFINITIONS @interface NoSynthObject : NSObject { NSString *ns_string; - // expected-warning@-1{{Instance variable 'ns_string' in 'NoSynthObject' is a raw pointer to retainable type 'NSString'}} + // expected-warning@-1{{Instance variable 'ns_string' (of 'NoSynthObject') is a raw pointer to RetainPtr-capable type 'NSString'}} CFStringRef cf_string; - // expected-warning@-1{{Instance variable 'cf_string' in 'NoSynthObject' is a retainable type 'CFStringRef'}} + // expected-warning@-1{{Instance variable 'cf_string' (of 'NoSynthObject') is a RetainPtr-capable type 'CFStringRef'}} dispatch_queue_t dispatch; - // expected-warning@-1{{Instance variable 'dispatch' in 'NoSynthObject' is a retainable type 'dispatch_queue_t'}} + // expected-warning@-1{{Instance variable 'dispatch' (of 'NoSynthObject') is a RetainPtr-capable type 'dispatch_queue_t'}} } @property(nonatomic, readonly, strong) NSString *prop_string1; @property(nonatomic, readonly, strong) NSString *prop_string2; @property(nonatomic, assign) NSString *prop_string3; -// expected-warning@-1{{Property 'prop_string3' in 'NoSynthObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}} +// expected-warning@-1{{Property 'prop_string3' (of 'NoSynthObject') is a raw pointer to RetainPtr-capable type 'NSString'}} @property(nonatomic, unsafe_unretained) NSString *prop_string4; -// expected-warning@-1{{Property 'prop_string4' in 'NoSynthObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}} +// expected-warning@-1{{Property 'prop_string4' (of 'NoSynthObject') is a raw pointer to RetainPtr-capable type 'NSString'}} @property(nonatomic, copy) NSString *prop_string5; @property(nonatomic, readonly, strong) dispatch_queue_t dispatch; @end diff --git a/clang/test/Analysis/malloc-failure.c b/clang/test/Analysis/malloc-failure.c index bf421fe7672c8..aea58dad470fa 100644 --- a/clang/test/Analysis/malloc-failure.c +++ b/clang/test/Analysis/malloc-failure.c @@ -71,6 +71,6 @@ void test_strdup() { void test_ifnameindex() { struct if_nameindex *p = if_nameindex(); - p->x = 1; //FIXME: if_nameindex is not recognized by the checker + p->x = 1; //expected-warning{{dereference of a null pointer}} if_freenameindex(p); } diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index 849ab3a3a0f37..a75144f041de0 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -1018,6 +1018,21 @@ void testWinWcsdupContentIsDefined(const wchar_t *s, unsigned validIndex) { free(s2); } +struct if_nameindex { char x; }; +struct if_nameindex *if_nameindex(void); +void if_freenameindex(struct if_nameindex *ptr); + +char testIfnameindex() { + struct if_nameindex *i = if_nameindex(); + return i->x; // expected-warning {{Potential leak of memory pointed to by}} +} + +void testIffreenameindex() { + struct if_nameindex *i = if_nameindex(); + char x = i->x; + if_freenameindex(i); +} // no warning + // ---------------------------------------------------------------------------- // Test the system library functions to which the pointer can escape. // This tests false positive suppression. diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp index d5219bcd74756..6b4b167d8f07f 100644 --- a/clang/test/CXX/drs/cwg25xx.cpp +++ b/clang/test/CXX/drs/cwg25xx.cpp @@ -247,9 +247,6 @@ namespace cwg2565 { // cwg2565: 16 open 2023-06-07 x; }; static_assert(ErrorRequires); - // since-cxx20-error@-1 {{static assertion failed}} \ - // since-cxx20-note@-1 {{because 'int' does not satisfy 'ErrorRequires'}} \ - // since-cxx20-note@#cwg2565-expr {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} template concept NestedErrorInRequires = requires (T x) { // #cwg2565-NEIR @@ -261,9 +258,6 @@ namespace cwg2565 { // cwg2565: 16 open 2023-06-07 }; }; static_assert(NestedErrorInRequires); - // since-cxx20-error@-1 {{static assertion failed}} \ - // since-cxx20-note@-1 {{because 'int' does not satisfy 'NestedErrorInRequires'}} \ - // since-cxx20-note-re@#cwg2565-NEIR-inner {{because {{.*}} would be invalid: constraint depends on a previously diagnosed expression}} #endif } // namespace cwg2565 diff --git a/clang/test/CXX/drs/cwg5xx.cpp b/clang/test/CXX/drs/cwg5xx.cpp index 935f3c7e41dc3..4062fcc04ce3d 100644 --- a/clang/test/CXX/drs/cwg5xx.cpp +++ b/clang/test/CXX/drs/cwg5xx.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98-23,cxx98-11,cxx98-14,cxx98-17,cxx98 -// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98-23,cxx98-11,cxx98-14,cxx98-17,since-cxx11 -// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98-23,cxx98-14,cxx98-17,since-cxx11 -// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98-23,since-cxx17,cxx98-17,since-cxx11 -// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98-23,since-cxx20,since-cxx17,since-cxx11 -// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98-23,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,since-cxx26,since-cxx23,since-cxx20,since-cxx17,since-cxx11 +// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -verify-directives -verify=expected,cxx98-23,cxx98-11,cxx98-14,cxx98-17,cxx98 +// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -verify-directives -verify=expected,cxx98-23,cxx98-11,cxx98-14,cxx98-17,since-cxx11 +// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -verify-directives -verify=expected,cxx98-23,cxx98-14,cxx98-17,since-cxx11 +// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -verify-directives -verify=expected,cxx98-23,since-cxx17,cxx98-17,since-cxx11 +// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -verify-directives -verify=expected,cxx98-23,since-cxx20,since-cxx17,since-cxx11 +// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -verify-directives -verify=expected,cxx98-23,since-cxx23,since-cxx20,since-cxx17,since-cxx11 +// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -verify-directives -verify=expected,since-cxx26,since-cxx23,since-cxx20,since-cxx17,since-cxx11 #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) diff --git a/clang/test/CodeGen/AArch64/neon/fullfp16.c b/clang/test/CodeGen/AArch64/neon/fullfp16.c index cd93d30e7d2ae..71a5a7d98eb83 100644 --- a/clang/test/CodeGen/AArch64/neon/fullfp16.c +++ b/clang/test/CodeGen/AArch64/neon/fullfp16.c @@ -34,7 +34,7 @@ #include //===------------------------------------------------------===// -// 2.5.1.1. Addition +// 2.5.1.5. Addition //===------------------------------------------------------===// // ALL-LABEL: @test_vaddh_f16( float16_t test_vaddh_f16(float16_t a, float16_t b) { @@ -85,6 +85,52 @@ float16_t test_vdivh_f16(float16_t a, float16_t b) { return vdivh_f16(a, b); } +//===------------------------------------------------------===// +// 2.5.1.7. Maximum +//===------------------------------------------------------===// +// ALL-LABEL: test_vmaxh_f16 +float16_t test_vmaxh_f16(float16_t a, float16_t b) { +// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.fmax" + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) {{.*}} { +// LLVM: [[MAX:%.*]] = call half @llvm.aarch64.neon.fmax.f16(half [[A]], half [[B]]) +// LLVM: ret half [[MAX]] + return vmaxh_f16(a, b); +} + +// ALL-LABEL: test_vmaxnmh_f16 +float16_t test_vmaxnmh_f16(float16_t a, float16_t b) { +// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmaxnm" + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) {{.*}} { +// LLVM: [[MAX:%.*]] = call half @llvm.aarch64.neon.fmaxnm.f16(half [[A]], half [[B]]) +// LLVM: ret half [[MAX]] + return vmaxnmh_f16(a, b); +} + +//===------------------------------------------------------===// +// 2.5.1.8. Mimimum +//===------------------------------------------------------===// +// ALL-LABEL: test_vminh_f16 +float16_t test_vminh_f16(float16_t a, float16_t b) { +// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.fmin" + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) {{.*}} { +// LLVM: [[MIN:%.*]] = call half @llvm.aarch64.neon.fmin.f16(half [[A]], half [[B]]) +// LLVM: ret half [[MIN]] + return vminh_f16(a, b); +} + +// ALL-LABEL: test_vminnmh_f16 +float16_t test_vminnmh_f16(float16_t a, float16_t b) { +// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnm" + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) {{.*}} { +// LLVM: [[MIN:%.*]] = call half @llvm.aarch64.neon.fminnm.f16(half [[A]], half [[B]]) +// LLVM: ret half [[MIN]] + return vminnmh_f16(a, b); +} + //===------------------------------------------------------===// // 2.5.2.1. Bitwise equal to zero //===------------------------------------------------------===// @@ -260,6 +306,19 @@ float16_t test_vrndxh_f16(float16_t a) { return vrndxh_f16(a); } +//===------------------------------------------------------===// +// 2.5.1.4. Square root +//===------------------------------------------------------===// +// ALL-LABEL: test_vsqrth_f16 +float16_t test_vsqrth_f16(float16_t a) { +// CIR: cir.call_llvm_intrinsic "sqrt" + +// LLVM-SAME: half{{.*}} [[A:%.*]]) +// LLVM: [[SQR:%.*]] = call half @llvm.sqrt.f16(half [[A]]) +// LLVM: ret half [[SQR]] + return vsqrth_f16(a); +} + //===------------------------------------------------------===// // 2.5.4.1. Negate //===------------------------------------------------------===// diff --git a/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c b/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c index ad4a0e5eb7275..d519e4138adbf 100644 --- a/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c +++ b/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c @@ -291,13 +291,6 @@ uint64_t test_vcvtph_u64_f16 (float16_t a) { return vcvtph_u64_f16(a); } -// CHECK-LABEL: test_vsqrth_f16 -// CHECK: [[SQR:%.*]] = call half @llvm.sqrt.f16(half %a) -// CHECK: ret half [[SQR]] -float16_t test_vsqrth_f16(float16_t a) { - return vsqrth_f16(a); -} - // CHECK-LABEL: test_vcageh_f16 // CHECK: [[FACG:%.*]] = call i32 @llvm.aarch64.neon.facge.i32.f16(half %a, half %b) // CHECK: [[RET:%.*]] = trunc i32 [[FACG]] to i16 @@ -458,34 +451,6 @@ int64_t test_vcvth_n_u64_f16(float16_t a) { return vcvth_n_u64_f16(a, 1); } -// CHECK-LABEL: test_vmaxh_f16 -// CHECK: [[MAX:%.*]] = call half @llvm.aarch64.neon.fmax.f16(half %a, half %b) -// CHECK: ret half [[MAX]] -float16_t test_vmaxh_f16(float16_t a, float16_t b) { - return vmaxh_f16(a, b); -} - -// CHECK-LABEL: test_vmaxnmh_f16 -// CHECK: [[MAX:%.*]] = call half @llvm.aarch64.neon.fmaxnm.f16(half %a, half %b) -// CHECK: ret half [[MAX]] -float16_t test_vmaxnmh_f16(float16_t a, float16_t b) { - return vmaxnmh_f16(a, b); -} - -// CHECK-LABEL: test_vminh_f16 -// CHECK: [[MIN:%.*]] = call half @llvm.aarch64.neon.fmin.f16(half %a, half %b) -// CHECK: ret half [[MIN]] -float16_t test_vminh_f16(float16_t a, float16_t b) { - return vminh_f16(a, b); -} - -// CHECK-LABEL: test_vminnmh_f16 -// CHECK: [[MIN:%.*]] = call half @llvm.aarch64.neon.fminnm.f16(half %a, half %b) -// CHECK: ret half [[MIN]] -float16_t test_vminnmh_f16(float16_t a, float16_t b) { - return vminnmh_f16(a, b); -} - // CHECK-LABEL: test_vmulxh_f16 // CHECK: [[MUL:%.*]] = call half @llvm.aarch64.neon.fmulx.f16(half %a, half %b) // CHECK: ret half [[MUL]] diff --git a/clang/test/CodeGen/SystemZ/builtins-zos-cs.c b/clang/test/CodeGen/SystemZ/builtins-zos-cs.c new file mode 100644 index 0000000000000..d31bb537f210a --- /dev/null +++ b/clang/test/CodeGen/SystemZ/builtins-zos-cs.c @@ -0,0 +1,66 @@ +// REQUIRES: systemz-registered-target +// RUN: %clang_cc1 -triple s390x-none-zos %s -emit-llvm -o - | FileCheck -check-prefix=CHECK %s +// RUN: %clang_cc1 -triple s390x-linux-gnu %s -verify + +int test_cs(unsigned int *a, unsigned int *b, unsigned int c) { + return __cs(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__cs'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_cs +// CHECK: cmpxchg ptr {{.*}}, i32 {{.*}}, i32 {{.*}} seq_cst seq_cst, align 4 +// CHECK: store i32 {{.*}}, ptr {{.*}}, align 4 +// CHECK: xor i1 {{.*}}, true + +int test_cs1(int *a, int *b, int *c) { + return __cs1(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__cs1'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_cs1 +// CHECK: cmpxchg ptr {{.*}}, i32 {{.*}}, i32 {{.*}} seq_cst seq_cst, align 4 +// CHECK: store i32 {{.*}}, ptr {{.*}}, align 4 +// CHECK: xor i1 {{.*}}, true + +typedef struct __attribute__((__aligned__(8))) { + int a; + int b; +} double_word; + +int test_cds1(double_word *a, double_word *b, double_word *c) { + return __cds1(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__cds1'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_cds1 +// CHECK: cmpxchg ptr {{.*}}, i64 {{.*}}, i64 {{.*}} seq_cst seq_cst, align 8 +// CHECK: store i64 {{.*}}, ptr {{.*}}, align 8 +// CHECK: xor i1 {{.*}}, true + +typedef struct __attribute__((__aligned__(16))) { + int a; + int b; + int c; + int d; +} quadruple_word; + +int test_cdsg(quadruple_word *a, quadruple_word *b, quadruple_word *c) { + return __cdsg(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__cdsg'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_cdsg +// CHECK: cmpxchg ptr {{.*}}, i128 {{.*}}, i128 {{.*}} seq_cst seq_cst, align 16 +// CHECK: store i128 {{.*}}, ptr {{.*}}, align 16 +// CHECK: xor i1 {{.*}}, true + + +int test_csg(double_word *a, double_word *b, double_word *c) { + return __csg(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__csg'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_csg +// CHECK: cmpxchg ptr {{.*}}, i64 {{.*}}, i64 {{.*}} seq_cst seq_cst, align 8 +// CHECK: store i64 {{.*}}, ptr {{.*}}, align 8 +// CHECK: xor i1 {{.*}}, true diff --git a/clang/test/CodeGen/attr-cleanup-duplicate.c b/clang/test/CodeGen/attr-cleanup-duplicate.c new file mode 100644 index 0000000000000..3bf5cccfee4d4 --- /dev/null +++ b/clang/test/CodeGen/attr-cleanup-duplicate.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-unknown-linux %s | FileCheck %s + +// Tests for issue #207785. + +void f1(double *x); +void f2(double *x); +void f3(double *x); + +// CHECK-LABEL: define {{.*}} void @g1() +void g1() { + // CHECK: call void @f3 + // CHECK-NOT: call void @f2 + // CHECK-NOT: call void @f1 + __attribute__((cleanup(f1))) + __attribute__((cleanup(f2))) + __attribute__((cleanup(f3))) + double x; +} + +// CHECK-LABEL: define {{.*}} void @g2() +void g2() { + // CHECK: call void @f1 + __attribute__((cleanup(f1))) + __attribute__((cleanup(f1))) + double x; +} + +// CHECK-LABEL: define {{.*}} void @g3() +void g3() { + // CHECK: call void @f1 + // CHECK-NOT: call void @f2 + __attribute__((cleanup(f2))) + __attribute__((cleanup(f1))) + double x; +} + +// CHECK-LABEL: define {{.*}} void @g4() +void g4() { + // CHECK: call void @f1 + // CHECK-NOT: call void @f2 + [[gnu::cleanup(f2)]] + [[gnu::cleanup(f1)]] + double x; +} + +// CHECK-LABEL: define {{.*}} void @g5() +void g5() { + // CHECK: call void @f1 + // CHECK-NOT: call void @f2 + [[gnu::cleanup(f2)]] + __attribute__((cleanup(f1))) + double x; +} diff --git a/clang/test/CodeGen/builtin-cpu-supports-all.c b/clang/test/CodeGen/builtin-cpu-supports-all.c index c1274ccda827e..73ccf88dffd87 100644 --- a/clang/test/CodeGen/builtin-cpu-supports-all.c +++ b/clang/test/CodeGen/builtin-cpu-supports-all.c @@ -536,3 +536,8 @@ TEST_CPU_SUPPORTS(movrs, "movrs") // CHECK: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8) // CHECK: = and i32 [[LOAD]], 67108864 TEST_CPU_SUPPORTS(amx_movrs, "amx-movrs") + +// CHECK-LABEL: define{{.*}} void @test_avx512bmm( +// CHECK: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8) +// CHECK: = and i32 [[LOAD]], 134217728 +TEST_CPU_SUPPORTS(avx512bmm, "avx512bmm") diff --git a/clang/test/CodeGen/target-builtin-noerror.c b/clang/test/CodeGen/target-builtin-noerror.c index 1070f232a492a..86e74154cef4c 100644 --- a/clang/test/CodeGen/target-builtin-noerror.c +++ b/clang/test/CodeGen/target-builtin-noerror.c @@ -78,6 +78,7 @@ void verifyfeaturestrings(void) { (void)__builtin_cpu_supports("vpclmulqdq"); (void)__builtin_cpu_supports("avx512vnni"); (void)__builtin_cpu_supports("avx512bitalg"); + (void)__builtin_cpu_supports("avx512bmm"); (void)__builtin_cpu_supports("avx512bf16"); (void)__builtin_cpu_supports("avx512vp2intersect"); (void)__builtin_cpu_supports("f16c"); diff --git a/clang/test/CodeGenCXX/defaulted-function-fp-features.cpp b/clang/test/CodeGenCXX/defaulted-function-fp-features.cpp new file mode 100644 index 0000000000000..809c1fc864618 --- /dev/null +++ b/clang/test/CodeGenCXX/defaulted-function-fp-features.cpp @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++20 -emit-llvm -o - %s | FileCheck %s + +// CHECK-DAG: define {{.*}} @_ZeqRK6TargetS1_({{.*}}) [[NORMAL_ATTRS:#[0-9]+]] +// CHECK-DAG: define {{.*}} @_ZeqRK12StrictTargetS1_({{.*}}) [[STRICT_ATTRS:#[0-9]+]] +// CHECK-DAG: define {{.*}} @_ZN12AssignTargetaSERKS_({{.*}}) [[NORMAL_ATTRS]] +// CHECK-DAG: define {{.*}} @_ZN18StrictAssignTargetaSERKS_({{.*}}) [[STRICT_ATTRS]] + +// Templates +// CHECK-DAG: define {{.*}} @_ZeqRK14TemplateTargetIdES2_({{.*}}) [[NORMAL_ATTRS]] +// CHECK-DAG: define {{.*}} @_ZeqRK14TemplateTargetIfES2_({{.*}}) [[NORMAL_ATTRS]] +// CHECK-DAG: define {{.*}} @_ZeqRK20StrictTemplateTargetIdES2_({{.*}}) [[STRICT_ATTRS]] + +// --- NON-STRICT DECLARATIONS (at top of file, default FP is non-strict) --- + +struct Target { + double d; + friend bool operator==(const Target&, const Target&) = default; +}; + +struct Member { + double d; + Member& operator=(const Member& Other) { + d = Other.d + 1.0; + return *this; + } +}; + +struct AssignTarget { + Member m; +}; + +template +struct TemplateTarget { + T d; + friend bool operator==(const TemplateTarget&, const TemplateTarget&) = default; +}; + +// Trigger instantiation of TemplateTarget::operator== in non-strict context. +bool test_template_non_strict(TemplateTarget a, TemplateTarget b) { + return a == b; +} + + +// --- STRICT CONTEXT (pragmas enabled) --- +#pragma STDC FENV_ACCESS ON + +// Use-sites triggering synthesis of non-strict defaulted functions in strict context. + +bool test_non_strict_cmp(Target a, Target b) { + return a == b; +} + +void test_non_strict_assign(AssignTarget& a, AssignTarget& b) { + a = b; +} + +// Trigger instantiation of TemplateTarget::operator== in strict context. +// It should still be non-strict because the template was defined in non-strict context. +bool test_template_strict(TemplateTarget a, TemplateTarget b) { + return a == b; +} + +// Strict declarations (must get strictfp) + +struct StrictTarget { + double d; + friend bool operator==(const StrictTarget&, const StrictTarget&) = default; +}; + +bool test_strict_cmp(StrictTarget a, StrictTarget b) { + return a == b; +} + +struct StrictAssignTarget { + Member m; +}; + +void test_strict_assign(StrictAssignTarget& a, StrictAssignTarget& b) { + a = b; +} + +template +struct StrictTemplateTarget { + T d; + friend bool operator==(const StrictTemplateTarget&, const StrictTemplateTarget&) = default; +}; + + +// --- NON-STRICT CONTEXT AGAIN --- +#pragma STDC FENV_ACCESS OFF + +// Trigger instantiation of StrictTemplateTarget::operator== in non-strict context. +// It should be strict because the template was defined in strict context. +bool test_strict_template_non_strict(StrictTemplateTarget a, StrictTemplateTarget b) { + return a == b; +} + + +// CHECK-DAG: attributes [[STRICT_ATTRS]] = { {{.*}}strictfp{{.*}} } +// CHECK-DAG: attributes [[NORMAL_ATTRS]] = { {{.*}} } +// CHECK-NOT: attributes [[NORMAL_ATTRS]] = { {{.*}}strictfp diff --git a/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl b/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl index 87b6506c663b0..25f123a47649b 100644 --- a/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl +++ b/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl @@ -1,24 +1,33 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV +// Texture2D +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2D -DDXILTY=2 -DRW=0 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2D -DARRAYED=0 -DSAMPLED=1 -DFORMAT=0 -Texture2D Tex : register(t0); +// Texture2DArray +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2DArray -DDXILTY=7 -DRW=0 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2DArray -DARRAYED=1 -DSAMPLED=1 -DFORMAT=0 -// CHECK: define {{.*}} void @test_uint_dims() -// CHECK: call void @hlsl::Texture2D::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) +// RWTexture2D +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=RWTexture2D -DDXILTY=2 -DRW=1 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=RWTexture2D -DARRAYED=0 -DSAMPLED=2 -DFORMAT=1 + +// When RWTexture2DArray is implemented, add DXIL/SPIRV runs with DXILTY=7, RW=1, ARRAYED=1, SAMPLED=2, FORMAT=1. + +TEXTURE Tex; + +// CHECK: define {{.*}} void @test_uint_dims{{(\(\))?}}() +// CHECK: call void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) void test_uint_dims() { uint w, h; Tex.GetDimensions(w, h); } -// TODO: The test will have to be updated because the return type for the getdimensions intrinsic will no longer a overloaded. - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2D::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) +// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]] -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]]) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]]) +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 +// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]), ptr %[[HANDLE_GEP]] +// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]] +// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]]) +// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[HANDLE]]) // CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] // CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0 // CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]] @@ -26,21 +35,21 @@ void test_uint_dims() { // CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1 // CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]] -// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]]) -// CHECK: call void @hlsl::Texture2D::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) +// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %{{.*}}) +// CHECK: call void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) void test_uint_levels_dims(uint mipLevel) { uint w, h, l; Tex.GetDimensions(mipLevel, w, h, l); } -// CHECK: define linkonce_odr hidden void @hlsl::Texture2D::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) +// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]] +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 +// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]), ptr %[[HANDLE_GEP]] +// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]] // CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]] -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], i32 %[[MIP_VAL]]) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]]) +// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], i32 %[[MIP_VAL]]) +// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[HANDLE]], i32 %[[MIP_VAL]]) // CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] // CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0 // CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]] @@ -51,20 +60,20 @@ void test_uint_levels_dims(uint mipLevel) { // CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2 // CHECK: store i32 %[[L_VAL]], ptr %[[L_PTR]] -// CHECK: define {{.*}} void @test_float_dims() -// CHECK: call void @hlsl::Texture2D::GetDimensions(float&, float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) +// CHECK: define {{.*}} void @test_float_dims{{(\(\))?}}() +// CHECK: call void @hlsl::[[TEXTURE]]::GetDimensions(float&, float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) void test_float_dims() { float w, h; Tex.GetDimensions(w, h); } -// CHECK: define linkonce_odr hidden void @hlsl::Texture2D::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) +// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]] -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]]) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]]) +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 +// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]), ptr %[[HANDLE_GEP]] +// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]] +// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]]) +// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[HANDLE]]) // CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] // CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0 // CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float @@ -74,21 +83,21 @@ void test_float_dims() { // CHECK: %[[H_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[H_VAL]] to float // CHECK: store float %[[H_F]], ptr %[[H_PTR]] -// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]]) -// CHECK: call void @hlsl::Texture2D::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) +// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %{{.*}}) +// CHECK: call void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) void test_float_levels_dims(uint mipLevel) { float w, h, l; Tex.GetDimensions(mipLevel, w, h, l); } -// CHECK: define linkonce_odr hidden void @hlsl::Texture2D::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) +// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]] +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 +// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]), ptr %[[HANDLE_GEP]] +// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]] // CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]] -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], i32 %[[MIP_VAL]]) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]]) +// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], i32 %[[MIP_VAL]]) +// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[HANDLE]], i32 %[[MIP_VAL]]) // CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] // CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0 // CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float diff --git a/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl b/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl index 7c30a211149e7..d69a0f6ddaa89 100644 --- a/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl +++ b/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl @@ -1,238 +1,247 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV +// Texture2D +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DDXILTY=2 -DRW=0 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DARRAYED=0 -DSAMPLED=1 -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 -DFORMAT24=0 -DFORMAT25=0 -DRW=0 -Texture2D t; +// Texture2DArray +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -DLOCTY=int4 -DZEROS=" 0, 0" -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2DArray -DLOCSZ=4 -DCOORDSZ=3 -DARG3=", i32 2" -DDXILTY=7 -DRW=0 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -DLOCTY=int4 -DZEROS=" 0, 0" -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2DArray -DLOCSZ=4 -DCOORDSZ=3 -DARG3=", i32 2" -DARRAYED=1 -DSAMPLED=1 -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 -DFORMAT24=0 -DFORMAT25=0 -DRW=0 + +// RWTexture2D +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=RWTexture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DDXILTY=2 -DRW=1 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=RWTexture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DARRAYED=0 -DSAMPLED=2 -DFORMAT1=1 -DFORMAT3=3 -DFORMAT6=6 -DFORMAT21=21 -DFORMAT24=24 -DFORMAT25=25 + +TEXTURE t; // CHECK: define hidden {{.*}} <4 x float> @test_load(int vector[2]) -// CHECK: %[[COORD:.*]] = insertelement <3 x i32> {{.*}}, i32 0, i32 2 -// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t, <3 x i32> noundef %[[COORD]]) +// CHECK: %[[COORD:.*]] = insertelement <[[LOCSZ]] x i32> {{.*}}, i32 0, i32 [[COORDSZ]] +// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t, <[[LOCSZ]] x i32> noundef %[[COORD]]) // CHECK: ret <4 x float> %[[CALL]] float4 test_load(int2 loc : LOC) : SV_Target { - return t.Load(int3(loc, 0)); + return t.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) +// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) // CHECK: %[[THIS_ADDR:.*]] = alloca ptr -// CHECK: %[[LOCATION_ADDR:.*]] = alloca <3 x i32> +// CHECK: %[[LOCATION_ADDR:.*]] = alloca <[[LOCSZ]] x i32> // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]] -// CHECK: store <3 x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]] +// CHECK: store <[[LOCSZ]] x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]] // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 // CHECK: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", {{.*}}), ptr %[[HANDLE_GEP]] -// CHECK: %[[LOCATION_VAL:.*]] = load <3 x i32>, ptr %[[LOCATION_ADDR]] -// CHECK: %[[COORD:.*]] = shufflevector <3 x i32> %[[LOCATION_VAL]], <3 x i32> poison, <2 x i32> -// CHECK: %[[LOD:.*]] = extractelement <3 x i32> %[[LOCATION_VAL]], i64 2 -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) +// CHECK: %[[LOCATION_VAL:.*]] = load <[[LOCSZ]] x i32>, ptr %[[LOCATION_ADDR]] +// CHECK: %[[COORD:.*]] = shufflevector <[[LOCSZ]] x i32> %[[LOCATION_VAL]], <[[LOCSZ]] x i32> poison, <[[COORDSZ]] x i32> +// CHECK: %[[LOD:.*]] = extractelement <[[LOCSZ]] x i32> %[[LOCATION_VAL]], i64 [[COORDSZ]] +// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], <[[COORDSZ]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], <[[COORDSZ]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_load_offset(int vector[2]) -// CHECK: %[[COORD:.*]] = insertelement <3 x i32> {{.*}}, i32 0, i32 2 -// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t, <3 x i32> noundef %[[COORD]], <2 x i32> noundef splat (i32 1)) +// CHECK: %[[COORD:.*]] = insertelement <[[LOCSZ]] x i32> {{.*}}, i32 0, i32 [[COORDSZ]] +// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t, <[[LOCSZ]] x i32> noundef %[[COORD]], <2 x i32> noundef splat (i32 1)) // CHECK: ret <4 x float> %[[CALL]] float4 test_load_offset(int2 loc : LOC) : SV_Target { - return t.Load(int3(loc, 0), int2(1, 1)); + return t.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) // CHECK: %[[THIS_ADDR:.*]] = alloca ptr -// CHECK: %[[LOCATION_ADDR:.*]] = alloca <3 x i32> +// CHECK: %[[LOCATION_ADDR:.*]] = alloca <[[LOCSZ]] x i32> // CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32> // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]] -// CHECK: store <3 x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]] +// CHECK: store <[[LOCSZ]] x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]] // CHECK: store <2 x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]] // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 // CHECK: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", {{.*}}), ptr %[[HANDLE_GEP]] -// CHECK: %[[LOCATION_VAL:.*]] = load <3 x i32>, ptr %[[LOCATION_ADDR]] -// CHECK: %[[COORD:.*]] = shufflevector <3 x i32> %[[LOCATION_VAL]], <3 x i32> poison, <2 x i32> -// CHECK: %[[LOD:.*]] = extractelement <3 x i32> %[[LOCATION_VAL]], i64 2 +// CHECK: %[[LOCATION_VAL:.*]] = load <[[LOCSZ]] x i32>, ptr %[[LOCATION_ADDR]] +// CHECK: %[[COORD:.*]] = shufflevector <[[LOCSZ]] x i32> %[[LOCATION_VAL]], <[[LOCSZ]] x i32> poison, <[[COORDSZ]] x i32> +// CHECK: %[[LOD:.*]] = extractelement <[[LOCSZ]] x i32> %[[LOCATION_VAL]], i64 [[COORDSZ]] // CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) +// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], <[[COORDSZ]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) +// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], <[[COORDSZ]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) // CHECK: ret <4 x float> %[[RES]] // For the rest of the types, we just check that the call to the member // function has the correct return type. -Texture2D t_float; +TEXTURE t_float; // CHECK: define hidden {{.*}} float @test_load_float(int vector[2]) -// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", float, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret float %[[RES]] float test_load_float(int2 loc : LOC) { - return t_float.Load(int3(loc, 0)); + return t_float.Load(LOCTY(loc, ZEROS)); } // CHECK: define hidden {{.*}} float @test_load_offset_float(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_float, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret float %[[CALL]] float test_load_offset_float(int2 loc : LOC) { - return t_float.Load(int3(loc, 0), int2(1, 1)); + return t_float.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", float, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret float %[[RES]] -Texture2D t_float2; +TEXTURE t_float2; // CHECK: define hidden {{.*}} <2 x float> @test_load_float2(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_float2, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_float2, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <2 x float> %[[CALL]] float2 test_load_float2(int2 loc : LOC) { - return t_float2.Load(int3(loc, 0)); + return t_float2.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <2 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <2 x float> %[[RES]] // CHECK: define hidden {{.*}} <2 x float> @test_load_offset_float2(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_float2, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float2, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <2 x float> %[[CALL]] float2 test_load_offset_float2(int2 loc : LOC) { - return t_float2.Load(int3(loc, 0), int2(1, 1)); + return t_float2.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <2 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <2 x float> %[[RES]] -Texture2D t_float3; +TEXTURE t_float3; // CHECK: define hidden {{.*}} <3 x float> @test_load_float3(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_float3, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_float3, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <3 x float> %[[CALL]] float3 test_load_float3(int2 loc : LOC) { - return t_float3.Load(int3(loc, 0)); + return t_float3.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <3 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <3 x float> %[[RES]] // CHECK: define hidden {{.*}} <3 x float> @test_load_offset_float3(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_float3, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float3, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <3 x float> %[[CALL]] float3 test_load_offset_float3(int2 loc : LOC) { - return t_float3.Load(int3(loc, 0), int2(1, 1)); + return t_float3.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <3 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <3 x float> %[[RES]] -Texture2D t_int; +TEXTURE t_int; // CHECK: define hidden {{.*}} i32 @test_load_int(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_int, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret i32 %[[CALL]] int test_load_int(int2 loc : LOC) { - return t_int.Load(int3(loc, 0)); + return t_int.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", i32, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT24]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret i32 %[[RES]] // CHECK: define hidden {{.*}} i32 @test_load_offset_int(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret i32 %[[CALL]] int test_load_offset_int(int2 loc : LOC) { - return t_int.Load(int3(loc, 0), int2(1, 1)); + return t_int.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", i32, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT24]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret i32 %[[RES]] -Texture2D t_int2; +TEXTURE t_int2; // CHECK: define hidden {{.*}} <2 x i32> @test_load_int2(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_int2, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int2, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <2 x i32> %[[CALL]] int2 test_load_int2(int2 loc : LOC) { - return t_int2.Load(int3(loc, 0)); + return t_int2.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <2 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", <2 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <2 x i32> %[[RES]] // CHECK: define hidden {{.*}} <2 x i32> @test_load_offset_int2(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int2, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int2, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <2 x i32> %[[CALL]] int2 test_load_offset_int2(int2 loc : LOC) { - return t_int2.Load(int3(loc, 0), int2(1, 1)); + return t_int2.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <2 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", <2 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <2 x i32> %[[RES]] -Texture2D t_int3; +TEXTURE t_int3; // CHECK: define hidden {{.*}} <3 x i32> @test_load_int3(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_int3, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int3, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <3 x i32> %[[CALL]] int3 test_load_int3(int2 loc : LOC) { - return t_int3.Load(int3(loc, 0)); + return t_int3.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <3 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <3 x i32> %[[RES]] // CHECK: define hidden {{.*}} <3 x i32> @test_load_offset_int3(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int3, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int3, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <3 x i32> %[[CALL]] int3 test_load_offset_int3(int2 loc : LOC) { - return t_int3.Load(int3(loc, 0), int2(1, 1)); + return t_int3.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <3 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <3 x i32> %[[RES]] -Texture2D t_int4; +TEXTURE t_int4; // CHECK: define hidden {{.*}} <4 x i32> @test_load_int4(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_int4, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int4, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <4 x i32> %[[CALL]] int4 test_load_int4(int2 loc : LOC) { - return t_int4.Load(int3(loc, 0)); + return t_int4.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <4 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT21]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <4 x i32> %[[RES]] // CHECK: define hidden {{.*}} <4 x i32> @test_load_offset_int4(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int4, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int4, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <4 x i32> %[[CALL]] int4 test_load_offset_int4(int2 loc : LOC) { - return t_int4.Load(int3(loc, 0), int2(1, 1)); + return t_int4.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <4 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT21]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <4 x i32> %[[RES]] diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl deleted file mode 100644 index f295839be4887..0000000000000 --- a/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl +++ /dev/null @@ -1,103 +0,0 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV - -Texture2DArray Tex : register(t0); - -// CHECK: define {{.*}} void @test_uint_dims() -// CHECK: call void @hlsl::Texture2DArray::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) -void test_uint_dims() { - uint w, h; - Tex.GetDimensions(w, h); -} - -// TODO: The test will have to be updated because the return type for the getdimensions intrinsic will no longer a overloaded. - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) -// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]] -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]]) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]]) -// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] -// CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0 -// CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]] -// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]] -// CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1 -// CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]] - -// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]]) -// CHECK: call void @hlsl::Texture2DArray::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) -void test_uint_levels_dims(uint mipLevel) { - uint w, h, l; - Tex.GetDimensions(mipLevel, w, h, l); -} - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) -// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]] -// CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]] -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], i32 %[[MIP_VAL]]) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]]) -// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] -// CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0 -// CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]] -// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]] -// CHECK: %[[H_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 1 -// CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]] -// CHECK: %[[L_PTR:.*]] = load ptr, ptr %[[LEVELS]] -// CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2 -// CHECK: store i32 %[[L_VAL]], ptr %[[L_PTR]] - -// CHECK: define {{.*}} void @test_float_dims() -// CHECK: call void @hlsl::Texture2DArray::GetDimensions(float&, float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) -void test_float_dims() { - float w, h; - Tex.GetDimensions(w, h); -} - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) -// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]] -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]]) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]]) -// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] -// CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0 -// CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float -// CHECK: store float %[[W_F]], ptr %[[W_PTR]] -// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]] -// CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1 -// CHECK: %[[H_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[H_VAL]] to float -// CHECK: store float %[[H_F]], ptr %[[H_PTR]] - -// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]]) -// CHECK: call void @hlsl::Texture2DArray::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) -void test_float_levels_dims(uint mipLevel) { - float w, h, l; - Tex.GetDimensions(mipLevel, w, h, l); -} - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) -// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]] -// CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]] -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], i32 %[[MIP_VAL]]) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]]) -// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] -// CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0 -// CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float -// CHECK: store float %[[W_F]], ptr %[[W_PTR]] -// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]] -// CHECK: %[[H_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 1 -// CHECK: %[[H_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[H_VAL]] to float -// CHECK: store float %[[H_F]], ptr %[[H_PTR]] -// CHECK: %[[L_PTR:.*]] = load ptr, ptr %[[LEVELS]] -// CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2 -// CHECK: %[[L_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[L_VAL]] to float -// CHECK: store float %[[L_F]], ptr %[[L_PTR]] diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-s-buffer-load.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-s-buffer-load.cl new file mode 100644 index 0000000000000..0c640e5020267 --- /dev/null +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-s-buffer-load.cl @@ -0,0 +1,286 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu verde -emit-llvm -o - %s | FileCheck %s + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +typedef int v4i32 __attribute__((ext_vector_type(4))); +typedef int v2i32 __attribute__((ext_vector_type(2))); +typedef int v3i32 __attribute__((ext_vector_type(3))); +typedef int v8i32 __attribute__((ext_vector_type(8))); +typedef int v16i32 __attribute__((ext_vector_type(16))); +typedef float v2f32 __attribute__((ext_vector_type(2))); +typedef float v3f32 __attribute__((ext_vector_type(3))); +typedef float v4f32 __attribute__((ext_vector_type(4))); +typedef float v8f32 __attribute__((ext_vector_type(8))); +typedef float v16f32 __attribute__((ext_vector_type(16))); +typedef char v2i8 __attribute__((ext_vector_type(2))); +typedef char v3i8 __attribute__((ext_vector_type(3))); +typedef char v4i8 __attribute__((ext_vector_type(4))); +typedef half v2f16 __attribute__((ext_vector_type(2))); +typedef half v3f16 __attribute__((ext_vector_type(3))); +typedef half v4f16 __attribute__((ext_vector_type(4))); + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i32 [[TMP0]] +// +int test_amdgcn_s_buffer_load_i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_i32_non_const_offset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> [[RSRC_VEC:%.*]], i32 [[OFFSET:%.*]], i32 0) +// CHECK-NEXT: ret i32 [[TMP0]] +// +int test_amdgcn_s_buffer_load_i32_non_const_offset(__amdgpu_buffer_rsrc_t rsrc, int offset) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, offset, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v2i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i32> @llvm.amdgcn.s.buffer.load.v2i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x i32> [[TMP0]] +// +v2i32 test_amdgcn_s_buffer_load_v2i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v2i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v3i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x i32> @llvm.amdgcn.s.buffer.load.v3i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x i32> [[TMP0]] +// +v3i32 test_amdgcn_s_buffer_load_v3i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v3i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v4i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.amdgcn.s.buffer.load.v4i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +v4i32 test_amdgcn_s_buffer_load_v4i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v4i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v8i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.amdgcn.s.buffer.load.v8i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// +v8i32 test_amdgcn_s_buffer_load_v8i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v8i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v16i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i32> @llvm.amdgcn.s.buffer.load.v16i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <16 x i32> [[TMP0]] +// +v16i32 test_amdgcn_s_buffer_load_v16i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v16i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call float @llvm.amdgcn.s.buffer.load.f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret float [[TMP0]] +// +float test_amdgcn_s_buffer_load_f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v2f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x float> @llvm.amdgcn.s.buffer.load.v2f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x float> [[TMP0]] +// +v2f32 test_amdgcn_s_buffer_load_v2f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v2f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v3f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x float> @llvm.amdgcn.s.buffer.load.v3f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x float> [[TMP0]] +// +v3f32 test_amdgcn_s_buffer_load_v3f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v3f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v4f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.amdgcn.s.buffer.load.v4f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x float> [[TMP0]] +// +v4f32 test_amdgcn_s_buffer_load_v4f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v4f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v8f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.amdgcn.s.buffer.load.v8f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <8 x float> [[TMP0]] +// +v8f32 test_amdgcn_s_buffer_load_v8f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v8f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v16f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x float> @llvm.amdgcn.s.buffer.load.v16f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <16 x float> [[TMP0]] +// +v16f32 test_amdgcn_s_buffer_load_v16f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v16f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_i8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i8 @llvm.amdgcn.s.buffer.load.i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i8 [[TMP0]] +// +char test_amdgcn_s_buffer_load_i8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i8(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i8 @llvm.amdgcn.s.buffer.load.i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i8 [[TMP0]] +// +unsigned char test_amdgcn_s_buffer_load_u8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_u8(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_i16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.amdgcn.s.buffer.load.i16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i16 [[TMP0]] +// +short test_amdgcn_s_buffer_load_i16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.amdgcn.s.buffer.load.i16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i16 [[TMP0]] +// +unsigned short test_amdgcn_s_buffer_load_u16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_u16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call half @llvm.amdgcn.s.buffer.load.f16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret half [[TMP0]] +// +half test_amdgcn_s_buffer_load_f16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_f16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v2f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x half> @llvm.amdgcn.s.buffer.load.v2f16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x half> [[TMP0]] +// +v2f16 test_amdgcn_s_buffer_load_v2f16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v2f16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v3f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x half> @llvm.amdgcn.s.buffer.load.v3f16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x half> [[TMP0]] +// +v3f16 test_amdgcn_s_buffer_load_v3f16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v3f16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v4f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x half> @llvm.amdgcn.s.buffer.load.v4f16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x half> [[TMP0]] +// +v4f16 test_amdgcn_s_buffer_load_v4f16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v4f16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v2i8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i8> @llvm.amdgcn.s.buffer.load.v2i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x i8> [[TMP0]] +// +v2i8 test_amdgcn_s_buffer_load_v2i8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v2i8(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v3i8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x i8> @llvm.amdgcn.s.buffer.load.v3i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x i8> [[TMP0]] +// +v3i8 test_amdgcn_s_buffer_load_v3i8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v3i8(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v4i8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i8> @llvm.amdgcn.s.buffer.load.v4i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x i8> [[TMP0]] +// +v4i8 test_amdgcn_s_buffer_load_v4i8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v4i8(rsrc, /*offset=*/0, /*aux=*/0); +} diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index f18e820d15444..e11753b91de98 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -121,6 +121,11 @@ // BITALG: "-target-feature" "+avx512bitalg" // NO-BITALG: "-target-feature" "-avx512bitalg" +// RUN: %clang --target=i386 -march=i386 -mavx512bmm %s -### 2>&1 | FileCheck -check-prefix=BMM %s +// RUN: %clang --target=i386 -march=i386 -mno-avx512bmm %s -### 2>&1 | FileCheck -check-prefix=NO-BMM %s +// BMM: "-target-feature" "+avx512bmm" +// NO-BMM: "-target-feature" "-avx512bmm" + // RUN: %clang --target=i386 -march=i386 -mavx512vnni %s -### 2>&1 | FileCheck -check-prefix=VNNI %s // RUN: %clang --target=i386 -march=i386 -mno-avx512vnni %s -### 2>&1 | FileCheck -check-prefix=NO-VNNI %s // VNNI: "-target-feature" "+avx512vnni" diff --git a/clang/test/Headers/Inputs/zos/usr/include/stdlib.h b/clang/test/Headers/Inputs/zos/usr/include/stdlib.h new file mode 100644 index 0000000000000..30ccbdfebdada --- /dev/null +++ b/clang/test/Headers/Inputs/zos/usr/include/stdlib.h @@ -0,0 +1,3 @@ +#ifdef _EXT +#define __cs(x, y, z) __cs1(x, y, &(z)) +#endif diff --git a/clang/test/Headers/zos-cs-wrapper.c b/clang/test/Headers/zos-cs-wrapper.c new file mode 100644 index 0000000000000..03b30b0f8ddbd --- /dev/null +++ b/clang/test/Headers/zos-cs-wrapper.c @@ -0,0 +1,13 @@ +// REQUIRES: systemz-registered-target +// RUN: %clang -E --target=s390x-ibm-zos %s -mzos-sys-include=%S/Inputs/zos/usr/include | FileCheck %s --check-prefix=NOCS1 +// RUN: %clang -E --target=s390x-ibm-zos -D__CS1 %s -mzos-sys-include=%S/Inputs/zos/usr/include | FileCheck %s --check-prefix=CS1 + +#define _EXT +#include + +int func(unsigned int *a, unsigned int *b, unsigned int c) { + return __cs(a, b, c); +} + +// NOCS1: return __cs(a, b, c); +// CS1: return __cs1(a, b, &(c)); diff --git a/clang/test/Interpreter/emulated-tls.cpp b/clang/test/Interpreter/emulated-tls.cpp new file mode 100644 index 0000000000000..73afe172ef6d9 --- /dev/null +++ b/clang/test/Interpreter/emulated-tls.cpp @@ -0,0 +1,25 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-windows +// +// An inline function that odr-uses a non-zero-initialized thread_local is +// emitted as a weak (linkonce_odr) definition into every PartialTranslationUnit +// that references it. With emulated TLS that set includes an __emutls_t. +// symbol. When a later PTU re-defines the same weak set, ORC's +// IRMaterializationUnit::discard() must find each duplicated symbol in its +// SymbolToDefinition map. The emulated-TLS path used to register __emutls_t. +// in SymbolFlags but not SymbolToDefinition, so discarding it dereferenced +// end() -- an assertion failure in +Asserts builds and heap corruption +// otherwise. Two PTUs each pulling in the same inline worker reproduces it. +// +// RUN: cat %s | clang-repl | FileCheck %s + +extern "C" int printf(const char *, ...); +template struct HeavyThing { static thread_local int tls; }; +template thread_local int HeavyThing::tls = Tag + 1; +inline int worker() { return HeavyThing<1>::tls; } +int callA() { return worker(); } +int callB() { return worker(); } +auto r = printf("tls = %d, %d\n", callA(), callB()); +// CHECK: tls = 2, 2 + +%quit diff --git a/clang/test/Modules/templates.mm b/clang/test/Modules/templates.mm index 610de099d398d..567717491eb87 100644 --- a/clang/test/Modules/templates.mm +++ b/clang/test/Modules/templates.mm @@ -1,6 +1,9 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -verify %s -Wno-objc-root-class // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -verify %s -Wno-objc-root-class -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class -fexperimental-new-constant-interpreter | FileCheck %s + // expected-no-diagnostics // REQUIRES: x86-registered-target @import templates_left; diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp new file mode 100644 index 0000000000000..be3118906d197 --- /dev/null +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp @@ -0,0 +1,12098 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK3 + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK7 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK7 + +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK9 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK9 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK11 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK11 + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK13 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK13 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK15 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK15 + +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +void fn1(); +void fn2(); +void fn3(); +void fn4(); +void fn5(); +void fn6(); +void fn7(); + +int Arg; + +void gtid_test() { +#ifdef OMP5 +#pragma omp target teams distribute parallel for simd if(simd: true) nontemporal(Arg) +#else +#pragma omp target teams distribute parallel for simd +#endif // OMP5 + for (int i = 0; i < 100; i++) { + Arg = 0; + } + +#pragma omp target teams distribute parallel for simd if (parallel: false) + for(int i = 0 ; i < 100; i++) { + gtid_test(); + } +} + + +void gtid_test2() { +#ifdef OMP5 +#pragma omp target teams distribute parallel for simd if(simd: true) nontemporal(Arg) +#else +#pragma omp target teams distribute parallel for simd +#endif // OMP5 + for (int i = 0; i < 100; i++) { + Arg = 0; + } + +#pragma omp target teams distribute parallel for simd if (teams: false) + for(int i = 0 ; i < 100; i++) { + gtid_test2(); + } +} + + +template +int tmain(T Arg) { +#pragma omp target teams distribute parallel for simd if (true) + for(int i = 0 ; i < 100; i++) { + fn1(); + } +#pragma omp target teams distribute parallel for simd if (false) + for(int i = 0 ; i < 100; i++) { + fn2(); + } +#pragma omp target teams distribute parallel for simd if (parallel: Arg) + for(int i = 0 ; i < 100; i++) { + fn3(); + } +#pragma omp target teams distribute parallel for simd if (teams: Arg) + for(int i = 0 ; i < 100; i++) { + fn4(); + } + return 0; +} + +int main() { +#pragma omp target teams distribute parallel for simd if (true) + for(int i = 0 ; i < 100; i++) { + + + fn5(); + } + +#pragma omp target teams distribute parallel for simd if (false) + for(int i = 0 ; i < 100; i++) { + + + fn6(); + } + +#pragma omp target teams distribute parallel for simd if (Arg) + for(int i = 0 ; i < 100; i++) { + + + fn7(); + } + + return tmain(Arg); +} + + + + + + +// call void [[T_OUTLINE_FUN_3:@.+]]( + +#endif +// CHECK1-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK1-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes, ptr [[TMP15]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(i64 [[TMP1]], ptr null) #[[ATTR2:[0-9]+]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.1, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP35]], align 8 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP41]], align 4 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK1-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK1-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined, i64 [[TMP1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.3, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP15]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65(i64 [[TMP1]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.5, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP35]], align 8 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP41]], align 4 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK1-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK1-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined, i64 [[TMP1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP39:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP42:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP45:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@main +// CHECK1-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS5:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[_TMP7:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS8:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107(ptr null) #[[ATTR2]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK1-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP22]], ptr [[TMP25]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV6:%.*]] = icmp ne i8 [[TMP32]], 0 +// CHECK1-NEXT: [[TMP33:%.*]] = select i1 [[LOADEDV6]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP31]], ptr [[TMP38]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.10, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.11, ptr [[TMP40]], align 8 +// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP42]], align 8 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP43]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP44]], align 8 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP45]], align 4 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [[TMP34]], ptr [[TMP46]], align 4 +// CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP47]], align 4 +// CHECK1-NEXT: [[TMP48:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP33]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.region_id, ptr [[KERNEL_ARGS8]]) +// CHECK1-NEXT: [[TMP49:%.*]] = icmp ne i32 [[TMP48]], 0 +// CHECK1-NEXT: br i1 [[TMP49]], label [[OMP_OFFLOAD_FAILED9:%.*]], label [[OMP_OFFLOAD_CONT10:%.*]] +// CHECK1: omp_offload.failed9: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT10]] +// CHECK1: omp_offload.cont10: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP50]]) +// CHECK1-NEXT: ret i32 [[CALL]] +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP48:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP51:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP53:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn6v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114 +// CHECK1-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined, i64 [[TMP3]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56:![0-9]+]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK1-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then4: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK1: omp_if.else5: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK1: omp.inner.for.cond6: +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK1-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK1: omp.inner.for.body8: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK1-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK1-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK1: omp_if.then13: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK1-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK1: omp_if.else14: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_IF_END16]] +// CHECK1: omp_if.end16: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK1: omp.inner.for.inc17: +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK1-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK1: omp.inner.for.end19: +// CHECK1-NEXT: br label [[OMP_IF_END20]] +// CHECK1: omp_if.end20: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK1-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK1: cond.true5: +// CHECK1-NEXT: br label [[COND_END7:%.*]] +// CHECK1: cond.false6: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END7]] +// CHECK1: cond.end7: +// CHECK1-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK1-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK1: omp.inner.for.cond9: +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK1: omp.inner.for.body11: +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn7v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK1: omp.body.continue14: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK1: omp.inner.for.inc15: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK1: omp.inner.for.end17: +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9 +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK1: cond.true5: +// CHECK1-NEXT: br label [[COND_END7:%.*]] +// CHECK1: cond.false6: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END7]] +// CHECK1: cond.end7: +// CHECK1-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK1-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK1: omp.inner.for.cond9: +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK1: omp.inner.for.body11: +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn7v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK1: omp.body.continue14: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK1: omp.inner.for.inc15: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK1: omp.inner.for.end17: +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK1-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS2:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[_TMP6:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED14:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.12, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84(ptr null) #[[ATTR2]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK1-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP22]], ptr [[TMP23]], align 8 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP31:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV5:%.*]] = icmp ne i8 [[TMP31]], 0 +// CHECK1-NEXT: [[TMP32:%.*]] = select i1 [[LOADEDV5]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP33:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP32]], 0 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP34]], align 4 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP29]], ptr [[TMP36]], align 8 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.14, ptr [[TMP38]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP40]], align 8 +// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP42]], align 8 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP43]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP44]], align 4 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [[TMP33]], ptr [[TMP45]], align 4 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP46]], align 4 +// CHECK1-NEXT: [[TMP47:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP32]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.region_id, ptr [[KERNEL_ARGS7]]) +// CHECK1-NEXT: [[TMP48:%.*]] = icmp ne i32 [[TMP47]], 0 +// CHECK1-NEXT: br i1 [[TMP48]], label [[OMP_OFFLOAD_FAILED8:%.*]], label [[OMP_OFFLOAD_CONT9:%.*]] +// CHECK1: omp_offload.failed8: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT9]] +// CHECK1: omp_offload.cont9: +// CHECK1-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL11:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK1-NEXT: [[STOREDV12:%.*]] = zext i1 [[TOBOOL11]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV12]], ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK1-NEXT: [[LOADEDV13:%.*]] = icmp ne i8 [[TMP50]], 0 +// CHECK1-NEXT: [[STOREDV15:%.*]] = zext i1 [[LOADEDV13]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV15]], ptr [[DOTCAPTURE_EXPR__CASTED14]], align 1 +// CHECK1-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED14]], align 8 +// CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP51]], ptr [[TMP52]], align 8 +// CHECK1-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP51]], ptr [[TMP53]], align 8 +// CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP54]], align 8 +// CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP55]], align 8 +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP56]], align 8 +// CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP57]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP60]], align 4 +// CHECK1-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK1-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP58]], ptr [[TMP62]], align 8 +// CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP59]], ptr [[TMP63]], align 8 +// CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.16, ptr [[TMP64]], align 8 +// CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP65]], align 8 +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP66]], align 8 +// CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP67]], align 8 +// CHECK1-NEXT: [[TMP68:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP68]], align 8 +// CHECK1-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP69]], align 8 +// CHECK1-NEXT: [[TMP70:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP70]], align 4 +// CHECK1-NEXT: [[TMP71:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP71]], align 4 +// CHECK1-NEXT: [[TMP72:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP72]], align 4 +// CHECK1-NEXT: [[TMP73:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK1-NEXT: [[TMP74:%.*]] = icmp ne i32 [[TMP73]], 0 +// CHECK1-NEXT: br i1 [[TMP74]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK1: omp_offload.failed21: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92(i64 [[TMP51]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK1: omp_offload.cont22: +// CHECK1-NEXT: ret i32 0 +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP72:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP74:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn2v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP75:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88 +// CHECK1-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP0]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined, i64 [[TMP1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP77:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP80:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92 +// CHECK1-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP83:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP86:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK3-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes, ptr [[TMP15]], align 8 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK3-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46(i64 [[TMP1]], ptr null) #[[ATTR2:[0-9]+]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.1, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP35]], align 8 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP41]], align 4 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK3-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK3-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined, i64 [[TMP1]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21:![0-9]+]], !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK3-SAME: () #[[ATTR0]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.3, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP15]], align 8 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK3-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63(i64 [[TMP1]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.5, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP35]], align 8 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP41]], align 4 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK3-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK3-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined, i64 [[TMP1]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@main +// CHECK3-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS5:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[_TMP7:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS8:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107(ptr null) #[[ATTR2]] +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK3-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP22]], ptr [[TMP25]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP32:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV6:%.*]] = icmp ne i8 [[TMP32]], 0 +// CHECK3-NEXT: [[TMP33:%.*]] = select i1 [[LOADEDV6]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP31]], ptr [[TMP38]], align 8 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.10, ptr [[TMP39]], align 8 +// CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.11, ptr [[TMP40]], align 8 +// CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP42]], align 8 +// CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP43]], align 8 +// CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP44]], align 8 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP45]], align 4 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [[TMP34]], ptr [[TMP46]], align 4 +// CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP47]], align 4 +// CHECK3-NEXT: [[TMP48:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP33]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.region_id, ptr [[KERNEL_ARGS8]]) +// CHECK3-NEXT: [[TMP49:%.*]] = icmp ne i32 [[TMP48]], 0 +// CHECK3-NEXT: br i1 [[TMP49]], label [[OMP_OFFLOAD_FAILED9:%.*]], label [[OMP_OFFLOAD_CONT10:%.*]] +// CHECK3: omp_offload.failed9: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT10]] +// CHECK3: omp_offload.cont10: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP50]]) +// CHECK3-NEXT: ret i32 [[CALL]] +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP54:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn6v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP56:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114 +// CHECK3-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined, i64 [[TMP3]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57:![0-9]+]] +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK3-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then4: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP58:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK3: omp_if.else5: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK3: omp.inner.for.cond6: +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK3-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK3: omp.inner.for.body8: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK3-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK3-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK3-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK3: omp_if.then13: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK3-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK3: omp_if.else14: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_IF_END16]] +// CHECK3: omp_if.end16: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK3: omp.inner.for.inc17: +// CHECK3-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK3-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP60:![0-9]+]] +// CHECK3: omp.inner.for.end19: +// CHECK3-NEXT: br label [[OMP_IF_END20]] +// CHECK3: omp_if.end20: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK3-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61:![0-9]+]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP62:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK3-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK3: cond.true5: +// CHECK3-NEXT: br label [[COND_END7:%.*]] +// CHECK3: cond.false6: +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END7]] +// CHECK3: cond.end7: +// CHECK3-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK3-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK3: omp.inner.for.cond9: +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK3: omp.inner.for.body11: +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK3-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn7v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK3: omp.body.continue14: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK3: omp.inner.for.inc15: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK3-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP64:![0-9]+]] +// CHECK3: omp.inner.for.end17: +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9 +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65:![0-9]+]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP66:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK3-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK3: cond.true5: +// CHECK3-NEXT: br label [[COND_END7:%.*]] +// CHECK3: cond.false6: +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END7]] +// CHECK3: cond.end7: +// CHECK3-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK3-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK3: omp.inner.for.cond9: +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK3: omp.inner.for.body11: +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK3-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn7v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK3: omp.body.continue14: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK3: omp.inner.for.inc15: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK3-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP68:![0-9]+]] +// CHECK3: omp.inner.for.end17: +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK3-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS2:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[_TMP6:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED14:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.12, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84(ptr null) #[[ATTR2]] +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK3-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP22]], ptr [[TMP23]], align 8 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP31:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV5:%.*]] = icmp ne i8 [[TMP31]], 0 +// CHECK3-NEXT: [[TMP32:%.*]] = select i1 [[LOADEDV5]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP33:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP32]], 0 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP34]], align 4 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP29]], ptr [[TMP36]], align 8 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.14, ptr [[TMP38]], align 8 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP39]], align 8 +// CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP40]], align 8 +// CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP42]], align 8 +// CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP43]], align 8 +// CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP44]], align 4 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [[TMP33]], ptr [[TMP45]], align 4 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP46]], align 4 +// CHECK3-NEXT: [[TMP47:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP32]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.region_id, ptr [[KERNEL_ARGS7]]) +// CHECK3-NEXT: [[TMP48:%.*]] = icmp ne i32 [[TMP47]], 0 +// CHECK3-NEXT: br i1 [[TMP48]], label [[OMP_OFFLOAD_FAILED8:%.*]], label [[OMP_OFFLOAD_CONT9:%.*]] +// CHECK3: omp_offload.failed8: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT9]] +// CHECK3: omp_offload.cont9: +// CHECK3-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL11:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK3-NEXT: [[STOREDV12:%.*]] = zext i1 [[TOBOOL11]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV12]], ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK3-NEXT: [[TMP50:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK3-NEXT: [[LOADEDV13:%.*]] = icmp ne i8 [[TMP50]], 0 +// CHECK3-NEXT: [[STOREDV15:%.*]] = zext i1 [[LOADEDV13]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV15]], ptr [[DOTCAPTURE_EXPR__CASTED14]], align 1 +// CHECK3-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED14]], align 8 +// CHECK3-NEXT: [[TMP52:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP51]], ptr [[TMP52]], align 8 +// CHECK3-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP51]], ptr [[TMP53]], align 8 +// CHECK3-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP54]], align 8 +// CHECK3-NEXT: [[TMP55:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP55]], align 8 +// CHECK3-NEXT: [[TMP56:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP56]], align 8 +// CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP57]], align 8 +// CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP60]], align 4 +// CHECK3-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK3-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP58]], ptr [[TMP62]], align 8 +// CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP59]], ptr [[TMP63]], align 8 +// CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.16, ptr [[TMP64]], align 8 +// CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP65]], align 8 +// CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP66]], align 8 +// CHECK3-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP67]], align 8 +// CHECK3-NEXT: [[TMP68:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP68]], align 8 +// CHECK3-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP69]], align 8 +// CHECK3-NEXT: [[TMP70:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP70]], align 4 +// CHECK3-NEXT: [[TMP71:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP71]], align 4 +// CHECK3-NEXT: [[TMP72:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP72]], align 4 +// CHECK3-NEXT: [[TMP73:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK3-NEXT: [[TMP74:%.*]] = icmp ne i32 [[TMP73]], 0 +// CHECK3-NEXT: br i1 [[TMP74]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK3: omp_offload.failed21: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92(i64 [[TMP51]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK3: omp_offload.cont22: +// CHECK3-NEXT: ret i32 0 +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP70:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP75:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn2v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88 +// CHECK3-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP0]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined, i64 [[TMP1]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92 +// CHECK3-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK5-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: store i32 0, ptr @Arg, align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK5-SAME: () #[[ATTR0]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: store i32 0, ptr @Arg, align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@main +// CHECK5-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK5-NEXT: call void @_Z3fn6v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK5-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK5-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK5-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK5: omp_if.then: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK5: omp.inner.for.cond21: +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK5-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK5-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK5: omp.inner.for.body23: +// CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK5-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK5-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK5: omp.body.continue26: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK5: omp.inner.for.inc27: +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK5-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK5: omp.inner.for.end29: +// CHECK5-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK5: omp_if.else: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK5: omp.inner.for.cond30: +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK5-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK5: omp.inner.for.body32: +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK5-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK5-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK5-NEXT: call void @_Z3fn7v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK5: omp.body.continue35: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK5: omp.inner.for.inc36: +// CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK5-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK5: omp.inner.for.end38: +// CHECK5-NEXT: br label [[OMP_IF_END]] +// CHECK5: omp_if.end: +// CHECK5-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK5-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK5-NEXT: ret i32 [[CALL]] +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK5-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_30:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP33:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB34:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB35:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV36:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK5-NEXT: call void @_Z3fn2v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK5-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK5: omp.inner.for.cond21: +// CHECK5-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK5-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK5: omp.inner.for.body23: +// CHECK5-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK5-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK5-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK5: omp.body.continue26: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK5: omp.inner.for.inc27: +// CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK5-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK5: omp.inner.for.end29: +// CHECK5-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: [[TOBOOL31:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK5-NEXT: [[STOREDV32:%.*]] = zext i1 [[TOBOOL31]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV32]], ptr [[DOTCAPTURE_EXPR_30]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB34]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB35]], align 4 +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB34]], align 4 +// CHECK5-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV36]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND38:%.*]] +// CHECK5: omp.inner.for.cond38: +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB35]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[CMP39:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK5-NEXT: br i1 [[CMP39]], label [[OMP_INNER_FOR_BODY40:%.*]], label [[OMP_INNER_FOR_END46:%.*]] +// CHECK5: omp.inner.for.body40: +// CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[MUL41:%.*]] = mul nsw i32 [[TMP20]], 1 +// CHECK5-NEXT: [[ADD42:%.*]] = add nsw i32 0, [[MUL41]] +// CHECK5-NEXT: store i32 [[ADD42]], ptr [[I37]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE43:%.*]] +// CHECK5: omp.body.continue43: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC44:%.*]] +// CHECK5: omp.inner.for.inc44: +// CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP21]], 1 +// CHECK5-NEXT: store i32 [[ADD45]], ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND38]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK5: omp.inner.for.end46: +// CHECK5-NEXT: store i32 100, ptr [[I37]], align 4 +// CHECK5-NEXT: ret i32 0 +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK7-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: store i32 0, ptr @Arg, align 4, !nontemporal [[META2:![0-9]+]], !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6:![0-9]+]] +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP7:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: ret void +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK7-SAME: () #[[ATTR0]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: store i32 0, ptr @Arg, align 4, !nontemporal [[META2]], !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12:![0-9]+]] +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP13:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: ret void +// +// +// CHECK7-LABEL: define {{[^@]+}}@main +// CHECK7-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK7-NEXT: call void @_Z3fn6v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP18:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK7-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK7-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK7-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK7: omp_if.then: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK7: omp.inner.for.cond21: +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK7-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK7-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK7: omp.inner.for.body23: +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK7-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK7-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK7: omp.body.continue26: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK7: omp.inner.for.inc27: +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK7-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK7: omp.inner.for.end29: +// CHECK7-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK7: omp_if.else: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK7: omp.inner.for.cond30: +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK7-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK7: omp.inner.for.body32: +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK7-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK7-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK7-NEXT: call void @_Z3fn7v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK7: omp.body.continue35: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK7: omp.inner.for.inc36: +// CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK7-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP23:![0-9]+]] +// CHECK7: omp.inner.for.end38: +// CHECK7-NEXT: br label [[OMP_IF_END]] +// CHECK7: omp_if.end: +// CHECK7-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK7-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK7-NEXT: ret i32 [[CALL]] +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK7-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_30:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP33:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB34:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB35:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV36:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK7-NEXT: call void @_Z3fn2v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK7-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK7: omp.inner.for.cond21: +// CHECK7-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK7-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK7: omp.inner.for.body23: +// CHECK7-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK7-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK7-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK7: omp.body.continue26: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK7: omp.inner.for.inc27: +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK7-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK7: omp.inner.for.end29: +// CHECK7-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: [[TOBOOL31:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK7-NEXT: [[STOREDV32:%.*]] = zext i1 [[TOBOOL31]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV32]], ptr [[DOTCAPTURE_EXPR_30]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB34]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB35]], align 4 +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB34]], align 4 +// CHECK7-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV36]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND38:%.*]] +// CHECK7: omp.inner.for.cond38: +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31:![0-9]+]] +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB35]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: [[CMP39:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK7-NEXT: br i1 [[CMP39]], label [[OMP_INNER_FOR_BODY40:%.*]], label [[OMP_INNER_FOR_END46:%.*]] +// CHECK7: omp.inner.for.body40: +// CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: [[MUL41:%.*]] = mul nsw i32 [[TMP20]], 1 +// CHECK7-NEXT: [[ADD42:%.*]] = add nsw i32 0, [[MUL41]] +// CHECK7-NEXT: store i32 [[ADD42]], ptr [[I37]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE43:%.*]] +// CHECK7: omp.body.continue43: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC44:%.*]] +// CHECK7: omp.inner.for.inc44: +// CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP21]], 1 +// CHECK7-NEXT: store i32 [[ADD45]], ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND38]], !llvm.loop [[LOOP32:![0-9]+]] +// CHECK7: omp.inner.for.end46: +// CHECK7-NEXT: store i32 100, ptr [[I37]], align 4 +// CHECK7-NEXT: ret i32 0 +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK9-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes, ptr [[TMP15]], align 8 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK9-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(i64 [[TMP1]], ptr null) #[[ATTR2:[0-9]+]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.1, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP35]], align 8 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP41]], align 4 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK9-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK9-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined, i64 [[TMP1]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK9-SAME: () #[[ATTR0]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.3, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP15]], align 8 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK9-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65(i64 [[TMP1]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.5, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP35]], align 8 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP41]], align 4 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK9-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK9-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined, i64 [[TMP1]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP39:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP42:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP45:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@main +// CHECK9-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS5:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[_TMP7:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS8:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107(ptr null) #[[ATTR2]] +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK9-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP22]], ptr [[TMP25]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP32:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV6:%.*]] = icmp ne i8 [[TMP32]], 0 +// CHECK9-NEXT: [[TMP33:%.*]] = select i1 [[LOADEDV6]], i32 0, i32 1 +// CHECK9-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP31]], ptr [[TMP38]], align 8 +// CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.10, ptr [[TMP39]], align 8 +// CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.11, ptr [[TMP40]], align 8 +// CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP42]], align 8 +// CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP43]], align 8 +// CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP44]], align 8 +// CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP45]], align 4 +// CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [[TMP34]], ptr [[TMP46]], align 4 +// CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP47]], align 4 +// CHECK9-NEXT: [[TMP48:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP33]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.region_id, ptr [[KERNEL_ARGS8]]) +// CHECK9-NEXT: [[TMP49:%.*]] = icmp ne i32 [[TMP48]], 0 +// CHECK9-NEXT: br i1 [[TMP49]], label [[OMP_OFFLOAD_FAILED9:%.*]], label [[OMP_OFFLOAD_CONT10:%.*]] +// CHECK9: omp_offload.failed9: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT10]] +// CHECK9: omp_offload.cont10: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP50]]) +// CHECK9-NEXT: ret i32 [[CALL]] +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP48:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP51:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP53:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn6v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114 +// CHECK9-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined, i64 [[TMP3]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56:![0-9]+]] +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK9-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then4: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK9: omp_if.else5: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK9: omp.inner.for.cond6: +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK9-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK9: omp.inner.for.body8: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK9-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK9-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK9-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK9: omp_if.then13: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK9-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK9: omp_if.else14: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_IF_END16]] +// CHECK9: omp_if.end16: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK9: omp.inner.for.inc17: +// CHECK9-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK9-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK9: omp.inner.for.end19: +// CHECK9-NEXT: br label [[OMP_IF_END20]] +// CHECK9: omp_if.end20: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK9-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK9-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK9: cond.true5: +// CHECK9-NEXT: br label [[COND_END7:%.*]] +// CHECK9: cond.false6: +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END7]] +// CHECK9: cond.end7: +// CHECK9-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK9-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK9: omp.inner.for.cond9: +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK9-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK9: omp.inner.for.body11: +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK9-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn7v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK9: omp.body.continue14: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK9: omp.inner.for.inc15: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK9-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK9: omp.inner.for.end17: +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9 +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK9-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK9: cond.true5: +// CHECK9-NEXT: br label [[COND_END7:%.*]] +// CHECK9: cond.false6: +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END7]] +// CHECK9: cond.end7: +// CHECK9-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK9-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK9: omp.inner.for.cond9: +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK9-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK9: omp.inner.for.body11: +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK9-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn7v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK9: omp.body.continue14: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK9: omp.inner.for.inc15: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK9-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK9: omp.inner.for.end17: +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK9-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS2:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[_TMP6:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED14:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.12, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84(ptr null) #[[ATTR2]] +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK9-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP22]], ptr [[TMP23]], align 8 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP31:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV5:%.*]] = icmp ne i8 [[TMP31]], 0 +// CHECK9-NEXT: [[TMP32:%.*]] = select i1 [[LOADEDV5]], i32 0, i32 1 +// CHECK9-NEXT: [[TMP33:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP32]], 0 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP34]], align 4 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP29]], ptr [[TMP36]], align 8 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.14, ptr [[TMP38]], align 8 +// CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP39]], align 8 +// CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP40]], align 8 +// CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP42]], align 8 +// CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP43]], align 8 +// CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP44]], align 4 +// CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [[TMP33]], ptr [[TMP45]], align 4 +// CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP46]], align 4 +// CHECK9-NEXT: [[TMP47:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP32]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.region_id, ptr [[KERNEL_ARGS7]]) +// CHECK9-NEXT: [[TMP48:%.*]] = icmp ne i32 [[TMP47]], 0 +// CHECK9-NEXT: br i1 [[TMP48]], label [[OMP_OFFLOAD_FAILED8:%.*]], label [[OMP_OFFLOAD_CONT9:%.*]] +// CHECK9: omp_offload.failed8: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT9]] +// CHECK9: omp_offload.cont9: +// CHECK9-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL11:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK9-NEXT: [[STOREDV12:%.*]] = zext i1 [[TOBOOL11]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV12]], ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK9-NEXT: [[TMP50:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK9-NEXT: [[LOADEDV13:%.*]] = icmp ne i8 [[TMP50]], 0 +// CHECK9-NEXT: [[STOREDV15:%.*]] = zext i1 [[LOADEDV13]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV15]], ptr [[DOTCAPTURE_EXPR__CASTED14]], align 1 +// CHECK9-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED14]], align 8 +// CHECK9-NEXT: [[TMP52:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP51]], ptr [[TMP52]], align 8 +// CHECK9-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP51]], ptr [[TMP53]], align 8 +// CHECK9-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP54]], align 8 +// CHECK9-NEXT: [[TMP55:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP55]], align 8 +// CHECK9-NEXT: [[TMP56:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP56]], align 8 +// CHECK9-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP57]], align 8 +// CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP60]], align 4 +// CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP58]], ptr [[TMP62]], align 8 +// CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP59]], ptr [[TMP63]], align 8 +// CHECK9-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.16, ptr [[TMP64]], align 8 +// CHECK9-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP65]], align 8 +// CHECK9-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP66]], align 8 +// CHECK9-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP67]], align 8 +// CHECK9-NEXT: [[TMP68:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP68]], align 8 +// CHECK9-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP69]], align 8 +// CHECK9-NEXT: [[TMP70:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP70]], align 4 +// CHECK9-NEXT: [[TMP71:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP71]], align 4 +// CHECK9-NEXT: [[TMP72:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP72]], align 4 +// CHECK9-NEXT: [[TMP73:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK9-NEXT: [[TMP74:%.*]] = icmp ne i32 [[TMP73]], 0 +// CHECK9-NEXT: br i1 [[TMP74]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK9: omp_offload.failed21: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92(i64 [[TMP51]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK9: omp_offload.cont22: +// CHECK9-NEXT: ret i32 0 +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP72:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP74:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn2v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP75:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88 +// CHECK9-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP0]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined, i64 [[TMP1]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP77:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP80:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92 +// CHECK9-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP83:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP86:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK11-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes, ptr [[TMP15]], align 8 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK11-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46(i64 [[TMP1]], ptr null) #[[ATTR2:[0-9]+]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.1, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP35]], align 8 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP41]], align 4 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK11-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK11-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined, i64 [[TMP1]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21:![0-9]+]], !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK11-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK11-SAME: () #[[ATTR0]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.3, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP15]], align 8 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK11-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63(i64 [[TMP1]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.5, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP35]], align 8 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP41]], align 4 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK11-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK11-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined, i64 [[TMP1]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK11-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@main +// CHECK11-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS5:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[_TMP7:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS8:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107(ptr null) #[[ATTR2]] +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK11-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP22]], ptr [[TMP25]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP32:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV6:%.*]] = icmp ne i8 [[TMP32]], 0 +// CHECK11-NEXT: [[TMP33:%.*]] = select i1 [[LOADEDV6]], i32 0, i32 1 +// CHECK11-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP31]], ptr [[TMP38]], align 8 +// CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.10, ptr [[TMP39]], align 8 +// CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.11, ptr [[TMP40]], align 8 +// CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP42]], align 8 +// CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP43]], align 8 +// CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP44]], align 8 +// CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP45]], align 4 +// CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [[TMP34]], ptr [[TMP46]], align 4 +// CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP47]], align 4 +// CHECK11-NEXT: [[TMP48:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP33]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.region_id, ptr [[KERNEL_ARGS8]]) +// CHECK11-NEXT: [[TMP49:%.*]] = icmp ne i32 [[TMP48]], 0 +// CHECK11-NEXT: br i1 [[TMP49]], label [[OMP_OFFLOAD_FAILED9:%.*]], label [[OMP_OFFLOAD_CONT10:%.*]] +// CHECK11: omp_offload.failed9: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT10]] +// CHECK11: omp_offload.cont10: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP50]]) +// CHECK11-NEXT: ret i32 [[CALL]] +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP54:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn6v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP56:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114 +// CHECK11-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined, i64 [[TMP3]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57:![0-9]+]] +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK11-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then4: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP58:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK11: omp_if.else5: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK11: omp.inner.for.cond6: +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK11-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK11: omp.inner.for.body8: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK11-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK11-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK11-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK11: omp_if.then13: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK11-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK11: omp_if.else14: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_IF_END16]] +// CHECK11: omp_if.end16: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK11: omp.inner.for.inc17: +// CHECK11-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK11-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP60:![0-9]+]] +// CHECK11: omp.inner.for.end19: +// CHECK11-NEXT: br label [[OMP_IF_END20]] +// CHECK11: omp_if.end20: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK11-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61:![0-9]+]] +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP62:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK11-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK11: cond.true5: +// CHECK11-NEXT: br label [[COND_END7:%.*]] +// CHECK11: cond.false6: +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END7]] +// CHECK11: cond.end7: +// CHECK11-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK11-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK11: omp.inner.for.cond9: +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK11-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK11: omp.inner.for.body11: +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK11-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn7v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK11: omp.body.continue14: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK11: omp.inner.for.inc15: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK11-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP64:![0-9]+]] +// CHECK11: omp.inner.for.end17: +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9 +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65:![0-9]+]] +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP66:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK11-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK11: cond.true5: +// CHECK11-NEXT: br label [[COND_END7:%.*]] +// CHECK11: cond.false6: +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END7]] +// CHECK11: cond.end7: +// CHECK11-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK11-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK11: omp.inner.for.cond9: +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK11-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK11: omp.inner.for.body11: +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK11-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn7v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK11: omp.body.continue14: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK11: omp.inner.for.inc15: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK11-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP68:![0-9]+]] +// CHECK11: omp.inner.for.end17: +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK11-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS2:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[_TMP6:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED14:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.12, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84(ptr null) #[[ATTR2]] +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK11-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP22]], ptr [[TMP23]], align 8 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP31:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV5:%.*]] = icmp ne i8 [[TMP31]], 0 +// CHECK11-NEXT: [[TMP32:%.*]] = select i1 [[LOADEDV5]], i32 0, i32 1 +// CHECK11-NEXT: [[TMP33:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP32]], 0 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP34]], align 4 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP29]], ptr [[TMP36]], align 8 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.14, ptr [[TMP38]], align 8 +// CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP39]], align 8 +// CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP40]], align 8 +// CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP42]], align 8 +// CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP43]], align 8 +// CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP44]], align 4 +// CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [[TMP33]], ptr [[TMP45]], align 4 +// CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP46]], align 4 +// CHECK11-NEXT: [[TMP47:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP32]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.region_id, ptr [[KERNEL_ARGS7]]) +// CHECK11-NEXT: [[TMP48:%.*]] = icmp ne i32 [[TMP47]], 0 +// CHECK11-NEXT: br i1 [[TMP48]], label [[OMP_OFFLOAD_FAILED8:%.*]], label [[OMP_OFFLOAD_CONT9:%.*]] +// CHECK11: omp_offload.failed8: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT9]] +// CHECK11: omp_offload.cont9: +// CHECK11-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL11:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK11-NEXT: [[STOREDV12:%.*]] = zext i1 [[TOBOOL11]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV12]], ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK11-NEXT: [[TMP50:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK11-NEXT: [[LOADEDV13:%.*]] = icmp ne i8 [[TMP50]], 0 +// CHECK11-NEXT: [[STOREDV15:%.*]] = zext i1 [[LOADEDV13]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV15]], ptr [[DOTCAPTURE_EXPR__CASTED14]], align 1 +// CHECK11-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED14]], align 8 +// CHECK11-NEXT: [[TMP52:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP51]], ptr [[TMP52]], align 8 +// CHECK11-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP51]], ptr [[TMP53]], align 8 +// CHECK11-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP54]], align 8 +// CHECK11-NEXT: [[TMP55:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP55]], align 8 +// CHECK11-NEXT: [[TMP56:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP56]], align 8 +// CHECK11-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP57]], align 8 +// CHECK11-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP60]], align 4 +// CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP58]], ptr [[TMP62]], align 8 +// CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP59]], ptr [[TMP63]], align 8 +// CHECK11-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.16, ptr [[TMP64]], align 8 +// CHECK11-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP65]], align 8 +// CHECK11-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP66]], align 8 +// CHECK11-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP67]], align 8 +// CHECK11-NEXT: [[TMP68:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP68]], align 8 +// CHECK11-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP69]], align 8 +// CHECK11-NEXT: [[TMP70:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP70]], align 4 +// CHECK11-NEXT: [[TMP71:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP71]], align 4 +// CHECK11-NEXT: [[TMP72:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP72]], align 4 +// CHECK11-NEXT: [[TMP73:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK11-NEXT: [[TMP74:%.*]] = icmp ne i32 [[TMP73]], 0 +// CHECK11-NEXT: br i1 [[TMP74]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK11: omp_offload.failed21: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92(i64 [[TMP51]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK11: omp_offload.cont22: +// CHECK11-NEXT: ret i32 0 +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP70:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP75:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn2v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88 +// CHECK11-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP0]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined, i64 [[TMP1]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK11-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92 +// CHECK11-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK13-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: store i32 0, ptr @Arg, align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK13-SAME: () #[[ATTR0]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: store i32 0, ptr @Arg, align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@main +// CHECK13-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK13-NEXT: call void @_Z3fn6v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK13-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK13-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK13-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK13: omp_if.then: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK13: omp.inner.for.cond21: +// CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK13-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK13: omp.inner.for.body23: +// CHECK13-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK13-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK13-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK13: omp.body.continue26: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK13: omp.inner.for.inc27: +// CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK13-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK13: omp.inner.for.end29: +// CHECK13-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK13: omp_if.else: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK13: omp.inner.for.cond30: +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK13-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK13: omp.inner.for.body32: +// CHECK13-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK13-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK13-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK13-NEXT: call void @_Z3fn7v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK13: omp.body.continue35: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK13: omp.inner.for.inc36: +// CHECK13-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK13-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK13: omp.inner.for.end38: +// CHECK13-NEXT: br label [[OMP_IF_END]] +// CHECK13: omp_if.end: +// CHECK13-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK13-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK13-NEXT: ret i32 [[CALL]] +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK13-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_30:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP33:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB34:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB35:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV36:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK13-NEXT: call void @_Z3fn2v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK13-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK13: omp.inner.for.cond21: +// CHECK13-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK13-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK13: omp.inner.for.body23: +// CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK13-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK13-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK13: omp.body.continue26: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK13: omp.inner.for.inc27: +// CHECK13-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK13-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK13: omp.inner.for.end29: +// CHECK13-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: [[TOBOOL31:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK13-NEXT: [[STOREDV32:%.*]] = zext i1 [[TOBOOL31]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV32]], ptr [[DOTCAPTURE_EXPR_30]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB34]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB35]], align 4 +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB34]], align 4 +// CHECK13-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV36]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND38:%.*]] +// CHECK13: omp.inner.for.cond38: +// CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK13-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB35]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[CMP39:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK13-NEXT: br i1 [[CMP39]], label [[OMP_INNER_FOR_BODY40:%.*]], label [[OMP_INNER_FOR_END46:%.*]] +// CHECK13: omp.inner.for.body40: +// CHECK13-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[MUL41:%.*]] = mul nsw i32 [[TMP20]], 1 +// CHECK13-NEXT: [[ADD42:%.*]] = add nsw i32 0, [[MUL41]] +// CHECK13-NEXT: store i32 [[ADD42]], ptr [[I37]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE43:%.*]] +// CHECK13: omp.body.continue43: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC44:%.*]] +// CHECK13: omp.inner.for.inc44: +// CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP21]], 1 +// CHECK13-NEXT: store i32 [[ADD45]], ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND38]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK13: omp.inner.for.end46: +// CHECK13-NEXT: store i32 100, ptr [[I37]], align 4 +// CHECK13-NEXT: ret i32 0 +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK15-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: store i32 0, ptr @Arg, align 4, !nontemporal [[META2:![0-9]+]], !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6:![0-9]+]] +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP7:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: ret void +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK15-SAME: () #[[ATTR0]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: store i32 0, ptr @Arg, align 4, !nontemporal [[META2]], !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12:![0-9]+]] +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP13:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: ret void +// +// +// CHECK15-LABEL: define {{[^@]+}}@main +// CHECK15-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK15-NEXT: call void @_Z3fn6v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP18:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK15-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK15-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK15-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK15: omp_if.then: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK15: omp.inner.for.cond21: +// CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK15-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK15: omp.inner.for.body23: +// CHECK15-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK15-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK15-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK15: omp.body.continue26: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK15: omp.inner.for.inc27: +// CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK15-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK15: omp.inner.for.end29: +// CHECK15-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK15: omp_if.else: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK15: omp.inner.for.cond30: +// CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK15-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK15: omp.inner.for.body32: +// CHECK15-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK15-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK15-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK15-NEXT: call void @_Z3fn7v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK15: omp.body.continue35: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK15: omp.inner.for.inc36: +// CHECK15-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK15-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP23:![0-9]+]] +// CHECK15: omp.inner.for.end38: +// CHECK15-NEXT: br label [[OMP_IF_END]] +// CHECK15: omp_if.end: +// CHECK15-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK15-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK15-NEXT: ret i32 [[CALL]] +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK15-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_30:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP33:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB34:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB35:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV36:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK15-NEXT: call void @_Z3fn2v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK15-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK15: omp.inner.for.cond21: +// CHECK15-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK15-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK15: omp.inner.for.body23: +// CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK15-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK15-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK15: omp.body.continue26: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK15: omp.inner.for.inc27: +// CHECK15-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK15-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK15: omp.inner.for.end29: +// CHECK15-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: [[TOBOOL31:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK15-NEXT: [[STOREDV32:%.*]] = zext i1 [[TOBOOL31]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV32]], ptr [[DOTCAPTURE_EXPR_30]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB34]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB35]], align 4 +// CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB34]], align 4 +// CHECK15-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV36]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND38:%.*]] +// CHECK15: omp.inner.for.cond38: +// CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31:![0-9]+]] +// CHECK15-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB35]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: [[CMP39:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK15-NEXT: br i1 [[CMP39]], label [[OMP_INNER_FOR_BODY40:%.*]], label [[OMP_INNER_FOR_END46:%.*]] +// CHECK15: omp.inner.for.body40: +// CHECK15-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: [[MUL41:%.*]] = mul nsw i32 [[TMP20]], 1 +// CHECK15-NEXT: [[ADD42:%.*]] = add nsw i32 0, [[MUL41]] +// CHECK15-NEXT: store i32 [[ADD42]], ptr [[I37]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE43:%.*]] +// CHECK15: omp.body.continue43: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC44:%.*]] +// CHECK15: omp.inner.for.inc44: +// CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP21]], 1 +// CHECK15-NEXT: store i32 [[ADD45]], ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND38]], !llvm.loop [[LOOP32:![0-9]+]] +// CHECK15: omp.inner.for.end46: +// CHECK15-NEXT: store i32 100, ptr [[I37]], align 4 +// CHECK15-NEXT: ret i32 0 +// diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp new file mode 100644 index 0000000000000..a612d9be52b77 --- /dev/null +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp @@ -0,0 +1,12190 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK3 + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK7 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK7 + +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK9 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK9 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK11 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK11 + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK13 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK13 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK15 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK15 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +void fn1(); +void fn2(); +void fn3(); +void fn4(); +void fn5(); +void fn6(); +void fn7(); + +int Arg; + +void gtid_test() { +#pragma omp target +#pragma omp teams distribute parallel for simd + for(int i = 0 ; i < 100; i++) {} + +#pragma omp target +#pragma omp teams distribute parallel for simd if (parallel: false) + for(int i = 0 ; i < 100; i++) { + gtid_test(); + } +} + + +void gtid_test2() { +#pragma omp target +#pragma omp teams distribute parallel for simd + for(int i = 0 ; i < 100; i++) {} + +#pragma omp target +#pragma omp teams distribute parallel for simd if (teams: false) + for(int i = 0 ; i < 100; i++) { + gtid_test2(); + } +} + + +template +int tmain(T Arg) { +#pragma omp target +#pragma omp teams distribute parallel for simd if (true) + for(int i = 0 ; i < 100; i++) { + fn1(); + } +#pragma omp target +#pragma omp teams distribute parallel for simd if (false) + for(int i = 0 ; i < 100; i++) { + fn2(); + } +#pragma omp target +#pragma omp teams distribute parallel for simd if (parallel: Arg) + for(int i = 0 ; i < 100; i++) { + fn3(); + } +#pragma omp target +#pragma omp teams distribute parallel for simd if (teams: Arg) + for(int i = 0 ; i < 100; i++) { + fn4(); + } + return 0; +} + +int main() { +#pragma omp target +#pragma omp teams distribute parallel for simd if (true) + for(int i = 0 ; i < 100; i++) { + + + fn5(); + } + +#pragma omp target +#pragma omp teams distribute parallel for simd if (false) + for(int i = 0 ; i < 100; i++) { + + + fn6(); + } + +#pragma omp target +#pragma omp teams distribute parallel for simd if (Arg) + for(int i = 0 ; i < 100; i++) { + + + fn7(); + } + + return tmain(Arg); +} + + + + + + +// call void [[T_OUTLINE_FUN_3:@.+]]( + + + +#endif +// CHECK1-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK1-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44(ptr null) #[[ATTR2:[0-9]+]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.1, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP30]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK1-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.3, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.5, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP30]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK1-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@main +// CHECK1-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.9, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.10, ptr [[TMP30]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK1-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK1-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.12, ptr [[TMP58]], align 8 +// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP59]], align 8 +// CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK1-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK1-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK1-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK1-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK1-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK1: omp_offload.failed13: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK1: omp_offload.cont14: +// CHECK1-NEXT: [[TMP69:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP69]]) +// CHECK1-NEXT: ret i32 [[CALL]] +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn6v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: [[TMP3:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP3]], 0 +// CHECK1-NEXT: [[STOREDV2:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV2]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined, i64 [[TMP4]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK1-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then4: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK1: omp_if.else5: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK1: omp.inner.for.cond6: +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK1-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK1: omp.inner.for.body8: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK1-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK1-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK1: omp_if.then13: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK1-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK1: omp_if.else14: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_IF_END16]] +// CHECK1: omp_if.end16: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK1: omp.inner.for.inc17: +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK1-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK1: omp.inner.for.end19: +// CHECK1-NEXT: br label [[OMP_IF_END20]] +// CHECK1: omp_if.end20: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK1-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK1: cond.true5: +// CHECK1-NEXT: br label [[COND_END7:%.*]] +// CHECK1: cond.false6: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END7]] +// CHECK1: cond.end7: +// CHECK1-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK1-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK1: omp.inner.for.cond9: +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK1: omp.inner.for.body11: +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn7v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK1: omp.body.continue14: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK1: omp.inner.for.inc15: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK1: omp.inner.for.end17: +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11 +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK1: cond.true5: +// CHECK1-NEXT: br label [[COND_END7:%.*]] +// CHECK1: cond.false6: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END7]] +// CHECK1: cond.end7: +// CHECK1-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK1-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK1: omp.inner.for.cond9: +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK1: omp.inner.for.body11: +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn7v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK1: omp.body.continue14: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK1: omp.inner.for.inc15: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP71:![0-9]+]] +// CHECK1: omp.inner.for.end17: +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK1-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[ARG_CASTED15:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.14, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.16, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP30]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK1-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK1-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.18, ptr [[TMP58]], align 8 +// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.19, ptr [[TMP59]], align 8 +// CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK1-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK1-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK1-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK1-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK1-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK1: omp_offload.failed13: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK1: omp_offload.cont14: +// CHECK1-NEXT: [[TMP69:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP69]], ptr [[ARG_CASTED15]], align 4 +// CHECK1-NEXT: [[TMP70:%.*]] = load i64, ptr [[ARG_CASTED15]], align 8 +// CHECK1-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP70]], ptr [[TMP71]], align 8 +// CHECK1-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP70]], ptr [[TMP72]], align 8 +// CHECK1-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP73]], align 8 +// CHECK1-NEXT: [[TMP74:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP74]], align 8 +// CHECK1-NEXT: [[TMP75:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP75]], align 8 +// CHECK1-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP76]], align 8 +// CHECK1-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP79:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP79]], align 4 +// CHECK1-NEXT: [[TMP80:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK1-NEXT: [[TMP81:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP77]], ptr [[TMP81]], align 8 +// CHECK1-NEXT: [[TMP82:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP78]], ptr [[TMP82]], align 8 +// CHECK1-NEXT: [[TMP83:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.20, ptr [[TMP83]], align 8 +// CHECK1-NEXT: [[TMP84:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.21, ptr [[TMP84]], align 8 +// CHECK1-NEXT: [[TMP85:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP85]], align 8 +// CHECK1-NEXT: [[TMP86:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP86]], align 8 +// CHECK1-NEXT: [[TMP87:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP87]], align 8 +// CHECK1-NEXT: [[TMP88:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP88]], align 8 +// CHECK1-NEXT: [[TMP89:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP89]], align 4 +// CHECK1-NEXT: [[TMP90:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP90]], align 4 +// CHECK1-NEXT: [[TMP91:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP91]], align 4 +// CHECK1-NEXT: [[TMP92:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK1-NEXT: [[TMP93:%.*]] = icmp ne i32 [[TMP92]], 0 +// CHECK1-NEXT: br i1 [[TMP93]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK1: omp_offload.failed21: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86(i64 [[TMP70]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK1: omp_offload.cont22: +// CHECK1-NEXT: ret i32 0 +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn2v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP79:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK1-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined, i64 [[TMP2]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK1-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP90:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK3-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44(ptr null) #[[ATTR2:[0-9]+]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.1, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP30]], align 8 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK3-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK3-SAME: () #[[ATTR0]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.3, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.5, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP30]], align 8 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK3-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@main +// CHECK3-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.9, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.10, ptr [[TMP30]], align 8 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK3-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK3-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK3-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK3-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK3-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.12, ptr [[TMP58]], align 8 +// CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP59]], align 8 +// CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK3-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK3-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK3-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK3-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK3-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK3: omp_offload.failed13: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK3: omp_offload.cont14: +// CHECK3-NEXT: [[TMP69:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP69]]) +// CHECK3-NEXT: ret i32 [[CALL]] +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn6v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: [[TMP3:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP3]], 0 +// CHECK3-NEXT: [[STOREDV2:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV2]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined, i64 [[TMP4]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK3-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then4: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK3: omp_if.else5: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK3: omp.inner.for.cond6: +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK3-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK3: omp.inner.for.body8: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK3-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK3-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK3-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK3: omp_if.then13: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK3-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK3: omp_if.else14: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_IF_END16]] +// CHECK3: omp_if.end16: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK3: omp.inner.for.inc17: +// CHECK3-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK3-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK3: omp.inner.for.end19: +// CHECK3-NEXT: br label [[OMP_IF_END20]] +// CHECK3: omp_if.end20: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK3-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK3-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK3: cond.true5: +// CHECK3-NEXT: br label [[COND_END7:%.*]] +// CHECK3: cond.false6: +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END7]] +// CHECK3: cond.end7: +// CHECK3-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK3-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK3: omp.inner.for.cond9: +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK3: omp.inner.for.body11: +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK3-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn7v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK3: omp.body.continue14: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK3: omp.inner.for.inc15: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK3-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK3: omp.inner.for.end17: +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11 +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK3-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK3: cond.true5: +// CHECK3-NEXT: br label [[COND_END7:%.*]] +// CHECK3: cond.false6: +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END7]] +// CHECK3: cond.end7: +// CHECK3-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK3-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK3: omp.inner.for.cond9: +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK3: omp.inner.for.body11: +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK3-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn7v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK3: omp.body.continue14: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK3: omp.inner.for.inc15: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK3-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP71:![0-9]+]] +// CHECK3: omp.inner.for.end17: +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK3-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[ARG_CASTED15:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.14, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.16, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP30]], align 8 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK3-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK3-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK3-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK3-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK3-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.18, ptr [[TMP58]], align 8 +// CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.19, ptr [[TMP59]], align 8 +// CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK3-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK3-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK3-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK3-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK3-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK3: omp_offload.failed13: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK3: omp_offload.cont14: +// CHECK3-NEXT: [[TMP69:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP69]], ptr [[ARG_CASTED15]], align 4 +// CHECK3-NEXT: [[TMP70:%.*]] = load i64, ptr [[ARG_CASTED15]], align 8 +// CHECK3-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP70]], ptr [[TMP71]], align 8 +// CHECK3-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP70]], ptr [[TMP72]], align 8 +// CHECK3-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP73]], align 8 +// CHECK3-NEXT: [[TMP74:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP74]], align 8 +// CHECK3-NEXT: [[TMP75:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP75]], align 8 +// CHECK3-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP76]], align 8 +// CHECK3-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP79:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP79]], align 4 +// CHECK3-NEXT: [[TMP80:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK3-NEXT: [[TMP81:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP77]], ptr [[TMP81]], align 8 +// CHECK3-NEXT: [[TMP82:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP78]], ptr [[TMP82]], align 8 +// CHECK3-NEXT: [[TMP83:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.20, ptr [[TMP83]], align 8 +// CHECK3-NEXT: [[TMP84:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.21, ptr [[TMP84]], align 8 +// CHECK3-NEXT: [[TMP85:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP85]], align 8 +// CHECK3-NEXT: [[TMP86:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP86]], align 8 +// CHECK3-NEXT: [[TMP87:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP87]], align 8 +// CHECK3-NEXT: [[TMP88:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP88]], align 8 +// CHECK3-NEXT: [[TMP89:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP89]], align 4 +// CHECK3-NEXT: [[TMP90:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP90]], align 4 +// CHECK3-NEXT: [[TMP91:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP91]], align 4 +// CHECK3-NEXT: [[TMP92:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK3-NEXT: [[TMP93:%.*]] = icmp ne i32 [[TMP92]], 0 +// CHECK3-NEXT: br i1 [[TMP93]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK3: omp_offload.failed21: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86(i64 [[TMP70]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK3: omp_offload.cont22: +// CHECK3-NEXT: ret i32 0 +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn2v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP79:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK3-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined, i64 [[TMP2]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK3-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP90:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK5-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK5-SAME: () #[[ATTR0]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@main +// CHECK5-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK5-NEXT: call void @_Z3fn6v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK5-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK5-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK5-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK5: omp_if.then: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK5: omp.inner.for.cond21: +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK5-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK5-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK5: omp.inner.for.body23: +// CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK5-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK5-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK5: omp.body.continue26: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK5: omp.inner.for.inc27: +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK5-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK5: omp.inner.for.end29: +// CHECK5-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK5: omp_if.else: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK5: omp.inner.for.cond30: +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK5-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK5: omp.inner.for.body32: +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK5-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK5-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK5-NEXT: call void @_Z3fn7v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK5: omp.body.continue35: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK5: omp.inner.for.inc36: +// CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK5-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK5: omp.inner.for.end38: +// CHECK5-NEXT: br label [[OMP_IF_END]] +// CHECK5: omp_if.end: +// CHECK5-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK5-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK5-NEXT: ret i32 [[CALL]] +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK5-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP30:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB31:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB32:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV33:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I34:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK5-NEXT: call void @_Z3fn2v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK5-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK5: omp.inner.for.cond21: +// CHECK5-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK5-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK5: omp.inner.for.body23: +// CHECK5-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK5-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK5-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK5: omp.body.continue26: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK5: omp.inner.for.inc27: +// CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK5-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK5: omp.inner.for.end29: +// CHECK5-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB31]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB32]], align 4 +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB31]], align 4 +// CHECK5-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV33]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND35:%.*]] +// CHECK5: omp.inner.for.cond35: +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB32]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[CMP36:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK5-NEXT: br i1 [[CMP36]], label [[OMP_INNER_FOR_BODY37:%.*]], label [[OMP_INNER_FOR_END43:%.*]] +// CHECK5: omp.inner.for.body37: +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[MUL38:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK5-NEXT: [[ADD39:%.*]] = add nsw i32 0, [[MUL38]] +// CHECK5-NEXT: store i32 [[ADD39]], ptr [[I34]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE40:%.*]] +// CHECK5: omp.body.continue40: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC41:%.*]] +// CHECK5: omp.inner.for.inc41: +// CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[ADD42:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK5-NEXT: store i32 [[ADD42]], ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND35]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK5: omp.inner.for.end43: +// CHECK5-NEXT: store i32 100, ptr [[I34]], align 4 +// CHECK5-NEXT: ret i32 0 +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK7-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: ret void +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK7-SAME: () #[[ATTR0]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: ret void +// +// +// CHECK7-LABEL: define {{[^@]+}}@main +// CHECK7-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK7-NEXT: call void @_Z3fn6v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK7-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK7-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK7-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK7: omp_if.then: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK7: omp.inner.for.cond21: +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK7-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK7-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK7: omp.inner.for.body23: +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK7-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK7-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK7: omp.body.continue26: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK7: omp.inner.for.inc27: +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK7-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK7: omp.inner.for.end29: +// CHECK7-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK7: omp_if.else: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK7: omp.inner.for.cond30: +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK7-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK7: omp.inner.for.body32: +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK7-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK7-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK7-NEXT: call void @_Z3fn7v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK7: omp.body.continue35: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK7: omp.inner.for.inc36: +// CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK7-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK7: omp.inner.for.end38: +// CHECK7-NEXT: br label [[OMP_IF_END]] +// CHECK7: omp_if.end: +// CHECK7-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK7-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK7-NEXT: ret i32 [[CALL]] +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK7-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP30:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB31:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB32:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV33:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I34:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK7-NEXT: call void @_Z3fn2v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK7-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK7: omp.inner.for.cond21: +// CHECK7-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK7-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK7: omp.inner.for.body23: +// CHECK7-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK7-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK7-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK7: omp.body.continue26: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK7: omp.inner.for.inc27: +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK7-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK7: omp.inner.for.end29: +// CHECK7-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB31]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB32]], align 4 +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB31]], align 4 +// CHECK7-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV33]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND35:%.*]] +// CHECK7: omp.inner.for.cond35: +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB32]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: [[CMP36:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK7-NEXT: br i1 [[CMP36]], label [[OMP_INNER_FOR_BODY37:%.*]], label [[OMP_INNER_FOR_END43:%.*]] +// CHECK7: omp.inner.for.body37: +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: [[MUL38:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK7-NEXT: [[ADD39:%.*]] = add nsw i32 0, [[MUL38]] +// CHECK7-NEXT: store i32 [[ADD39]], ptr [[I34]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE40:%.*]] +// CHECK7: omp.body.continue40: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC41:%.*]] +// CHECK7: omp.inner.for.inc41: +// CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: [[ADD42:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK7-NEXT: store i32 [[ADD42]], ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND35]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK7: omp.inner.for.end43: +// CHECK7-NEXT: store i32 100, ptr [[I34]], align 4 +// CHECK7-NEXT: ret i32 0 +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK9-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44(ptr null) #[[ATTR2:[0-9]+]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.1, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP30]], align 8 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK9-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK9-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK9-SAME: () #[[ATTR0]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.3, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.5, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP30]], align 8 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK9-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK9-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@main +// CHECK9-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.9, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.10, ptr [[TMP30]], align 8 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK9-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK9-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: [[TMP40:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK9-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK9-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK9-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK9-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK9-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK9-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK9-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.12, ptr [[TMP58]], align 8 +// CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP59]], align 8 +// CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK9-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK9-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK9-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK9-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK9-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK9-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK9: omp_offload.failed13: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK9: omp_offload.cont14: +// CHECK9-NEXT: [[TMP69:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP69]]) +// CHECK9-NEXT: ret i32 [[CALL]] +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn6v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: [[TMP3:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP3]], 0 +// CHECK9-NEXT: [[STOREDV2:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV2]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined, i64 [[TMP4]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK9-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then4: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK9: omp_if.else5: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK9: omp.inner.for.cond6: +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK9-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK9: omp.inner.for.body8: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK9-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK9-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK9-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK9: omp_if.then13: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK9-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK9: omp_if.else14: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_IF_END16]] +// CHECK9: omp_if.end16: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK9: omp.inner.for.inc17: +// CHECK9-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK9-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK9: omp.inner.for.end19: +// CHECK9-NEXT: br label [[OMP_IF_END20]] +// CHECK9: omp_if.end20: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK9-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK9-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK9: cond.true5: +// CHECK9-NEXT: br label [[COND_END7:%.*]] +// CHECK9: cond.false6: +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END7]] +// CHECK9: cond.end7: +// CHECK9-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK9-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK9: omp.inner.for.cond9: +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK9-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK9: omp.inner.for.body11: +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK9-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn7v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK9: omp.body.continue14: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK9: omp.inner.for.inc15: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK9-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK9: omp.inner.for.end17: +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11 +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK9-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK9: cond.true5: +// CHECK9-NEXT: br label [[COND_END7:%.*]] +// CHECK9: cond.false6: +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END7]] +// CHECK9: cond.end7: +// CHECK9-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK9-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK9: omp.inner.for.cond9: +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK9-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK9: omp.inner.for.body11: +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK9-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn7v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK9: omp.body.continue14: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK9: omp.inner.for.inc15: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK9-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP71:![0-9]+]] +// CHECK9: omp.inner.for.end17: +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK9-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[ARG_CASTED15:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.14, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.16, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP30]], align 8 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK9-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK9-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: [[TMP40:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK9-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK9-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK9-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK9-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK9-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK9-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK9-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.18, ptr [[TMP58]], align 8 +// CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.19, ptr [[TMP59]], align 8 +// CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK9-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK9-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK9-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK9-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK9-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK9-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK9: omp_offload.failed13: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK9: omp_offload.cont14: +// CHECK9-NEXT: [[TMP69:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP69]], ptr [[ARG_CASTED15]], align 4 +// CHECK9-NEXT: [[TMP70:%.*]] = load i64, ptr [[ARG_CASTED15]], align 8 +// CHECK9-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP70]], ptr [[TMP71]], align 8 +// CHECK9-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP70]], ptr [[TMP72]], align 8 +// CHECK9-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP73]], align 8 +// CHECK9-NEXT: [[TMP74:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP74]], align 8 +// CHECK9-NEXT: [[TMP75:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP75]], align 8 +// CHECK9-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP76]], align 8 +// CHECK9-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP79:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP79]], align 4 +// CHECK9-NEXT: [[TMP80:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK9-NEXT: [[TMP81:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP77]], ptr [[TMP81]], align 8 +// CHECK9-NEXT: [[TMP82:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP78]], ptr [[TMP82]], align 8 +// CHECK9-NEXT: [[TMP83:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.20, ptr [[TMP83]], align 8 +// CHECK9-NEXT: [[TMP84:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.21, ptr [[TMP84]], align 8 +// CHECK9-NEXT: [[TMP85:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP85]], align 8 +// CHECK9-NEXT: [[TMP86:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP86]], align 8 +// CHECK9-NEXT: [[TMP87:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP87]], align 8 +// CHECK9-NEXT: [[TMP88:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP88]], align 8 +// CHECK9-NEXT: [[TMP89:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP89]], align 4 +// CHECK9-NEXT: [[TMP90:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP90]], align 4 +// CHECK9-NEXT: [[TMP91:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP91]], align 4 +// CHECK9-NEXT: [[TMP92:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK9-NEXT: [[TMP93:%.*]] = icmp ne i32 [[TMP92]], 0 +// CHECK9-NEXT: br i1 [[TMP93]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK9: omp_offload.failed21: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86(i64 [[TMP70]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK9: omp_offload.cont22: +// CHECK9-NEXT: ret i32 0 +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn2v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP79:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK9-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined, i64 [[TMP2]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK9-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP90:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK11-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44(ptr null) #[[ATTR2:[0-9]+]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.1, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP30]], align 8 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK11-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK11-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK11-SAME: () #[[ATTR0]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.3, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.5, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP30]], align 8 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK11-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK11-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@main +// CHECK11-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.9, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.10, ptr [[TMP30]], align 8 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK11-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK11-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: [[TMP40:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK11-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK11-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK11-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK11-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK11-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK11-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK11-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK11-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.12, ptr [[TMP58]], align 8 +// CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP59]], align 8 +// CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK11-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK11-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK11-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK11-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK11-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK11-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK11: omp_offload.failed13: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK11: omp_offload.cont14: +// CHECK11-NEXT: [[TMP69:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP69]]) +// CHECK11-NEXT: ret i32 [[CALL]] +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn6v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: [[TMP3:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP3]], 0 +// CHECK11-NEXT: [[STOREDV2:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV2]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined, i64 [[TMP4]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK11-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then4: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK11: omp_if.else5: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK11: omp.inner.for.cond6: +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK11-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK11: omp.inner.for.body8: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK11-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK11-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK11-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK11: omp_if.then13: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK11-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK11: omp_if.else14: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_IF_END16]] +// CHECK11: omp_if.end16: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK11: omp.inner.for.inc17: +// CHECK11-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK11-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK11: omp.inner.for.end19: +// CHECK11-NEXT: br label [[OMP_IF_END20]] +// CHECK11: omp_if.end20: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK11-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK11-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK11: cond.true5: +// CHECK11-NEXT: br label [[COND_END7:%.*]] +// CHECK11: cond.false6: +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END7]] +// CHECK11: cond.end7: +// CHECK11-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK11-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK11: omp.inner.for.cond9: +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK11-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK11: omp.inner.for.body11: +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK11-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn7v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK11: omp.body.continue14: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK11: omp.inner.for.inc15: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK11-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK11: omp.inner.for.end17: +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11 +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK11-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK11: cond.true5: +// CHECK11-NEXT: br label [[COND_END7:%.*]] +// CHECK11: cond.false6: +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END7]] +// CHECK11: cond.end7: +// CHECK11-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK11-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK11: omp.inner.for.cond9: +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK11-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK11: omp.inner.for.body11: +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK11-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn7v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK11: omp.body.continue14: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK11: omp.inner.for.inc15: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK11-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP71:![0-9]+]] +// CHECK11: omp.inner.for.end17: +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK11-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[ARG_CASTED15:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.14, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.16, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP30]], align 8 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK11-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK11-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: [[TMP40:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK11-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK11-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK11-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK11-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK11-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK11-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK11-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK11-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.18, ptr [[TMP58]], align 8 +// CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.19, ptr [[TMP59]], align 8 +// CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK11-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK11-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK11-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK11-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK11-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK11-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK11: omp_offload.failed13: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK11: omp_offload.cont14: +// CHECK11-NEXT: [[TMP69:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP69]], ptr [[ARG_CASTED15]], align 4 +// CHECK11-NEXT: [[TMP70:%.*]] = load i64, ptr [[ARG_CASTED15]], align 8 +// CHECK11-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP70]], ptr [[TMP71]], align 8 +// CHECK11-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP70]], ptr [[TMP72]], align 8 +// CHECK11-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP73]], align 8 +// CHECK11-NEXT: [[TMP74:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP74]], align 8 +// CHECK11-NEXT: [[TMP75:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP75]], align 8 +// CHECK11-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP76]], align 8 +// CHECK11-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP79:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP79]], align 4 +// CHECK11-NEXT: [[TMP80:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK11-NEXT: [[TMP81:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP77]], ptr [[TMP81]], align 8 +// CHECK11-NEXT: [[TMP82:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP78]], ptr [[TMP82]], align 8 +// CHECK11-NEXT: [[TMP83:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.20, ptr [[TMP83]], align 8 +// CHECK11-NEXT: [[TMP84:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.21, ptr [[TMP84]], align 8 +// CHECK11-NEXT: [[TMP85:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP85]], align 8 +// CHECK11-NEXT: [[TMP86:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP86]], align 8 +// CHECK11-NEXT: [[TMP87:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP87]], align 8 +// CHECK11-NEXT: [[TMP88:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP88]], align 8 +// CHECK11-NEXT: [[TMP89:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP89]], align 4 +// CHECK11-NEXT: [[TMP90:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP90]], align 4 +// CHECK11-NEXT: [[TMP91:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP91]], align 4 +// CHECK11-NEXT: [[TMP92:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK11-NEXT: [[TMP93:%.*]] = icmp ne i32 [[TMP92]], 0 +// CHECK11-NEXT: br i1 [[TMP93]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK11: omp_offload.failed21: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86(i64 [[TMP70]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK11: omp_offload.cont22: +// CHECK11-NEXT: ret i32 0 +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn2v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP79:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK11-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined, i64 [[TMP2]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK11-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK11-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP90:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK13-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK13-SAME: () #[[ATTR0]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@main +// CHECK13-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK13-NEXT: call void @_Z3fn6v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK13-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK13-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK13-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK13: omp_if.then: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK13: omp.inner.for.cond21: +// CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK13-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK13: omp.inner.for.body23: +// CHECK13-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK13-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK13-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK13: omp.body.continue26: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK13: omp.inner.for.inc27: +// CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK13-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK13: omp.inner.for.end29: +// CHECK13-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK13: omp_if.else: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK13: omp.inner.for.cond30: +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK13-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK13: omp.inner.for.body32: +// CHECK13-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK13-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK13-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK13-NEXT: call void @_Z3fn7v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK13: omp.body.continue35: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK13: omp.inner.for.inc36: +// CHECK13-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK13-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK13: omp.inner.for.end38: +// CHECK13-NEXT: br label [[OMP_IF_END]] +// CHECK13: omp_if.end: +// CHECK13-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK13-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK13-NEXT: ret i32 [[CALL]] +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK13-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP30:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB31:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB32:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV33:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I34:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK13-NEXT: call void @_Z3fn2v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK13-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK13: omp.inner.for.cond21: +// CHECK13-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK13-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK13: omp.inner.for.body23: +// CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK13-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK13-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK13: omp.body.continue26: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK13: omp.inner.for.inc27: +// CHECK13-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK13-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK13: omp.inner.for.end29: +// CHECK13-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB31]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB32]], align 4 +// CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB31]], align 4 +// CHECK13-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV33]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND35:%.*]] +// CHECK13: omp.inner.for.cond35: +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB32]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[CMP36:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK13-NEXT: br i1 [[CMP36]], label [[OMP_INNER_FOR_BODY37:%.*]], label [[OMP_INNER_FOR_END43:%.*]] +// CHECK13: omp.inner.for.body37: +// CHECK13-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[MUL38:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK13-NEXT: [[ADD39:%.*]] = add nsw i32 0, [[MUL38]] +// CHECK13-NEXT: store i32 [[ADD39]], ptr [[I34]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE40:%.*]] +// CHECK13: omp.body.continue40: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC41:%.*]] +// CHECK13: omp.inner.for.inc41: +// CHECK13-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[ADD42:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK13-NEXT: store i32 [[ADD42]], ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND35]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK13: omp.inner.for.end43: +// CHECK13-NEXT: store i32 100, ptr [[I34]], align 4 +// CHECK13-NEXT: ret i32 0 +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK15-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: ret void +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK15-SAME: () #[[ATTR0]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: ret void +// +// +// CHECK15-LABEL: define {{[^@]+}}@main +// CHECK15-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK15-NEXT: call void @_Z3fn6v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK15-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK15-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK15-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK15: omp_if.then: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK15: omp.inner.for.cond21: +// CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK15-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK15: omp.inner.for.body23: +// CHECK15-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK15-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK15-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK15: omp.body.continue26: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK15: omp.inner.for.inc27: +// CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK15-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK15: omp.inner.for.end29: +// CHECK15-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK15: omp_if.else: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK15: omp.inner.for.cond30: +// CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK15-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK15: omp.inner.for.body32: +// CHECK15-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK15-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK15-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK15-NEXT: call void @_Z3fn7v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK15: omp.body.continue35: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK15: omp.inner.for.inc36: +// CHECK15-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK15-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK15: omp.inner.for.end38: +// CHECK15-NEXT: br label [[OMP_IF_END]] +// CHECK15: omp_if.end: +// CHECK15-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK15-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK15-NEXT: ret i32 [[CALL]] +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK15-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP30:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB31:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB32:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV33:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I34:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK15-NEXT: call void @_Z3fn2v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK15-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK15: omp.inner.for.cond21: +// CHECK15-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK15-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK15: omp.inner.for.body23: +// CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK15-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK15-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK15: omp.body.continue26: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK15: omp.inner.for.inc27: +// CHECK15-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK15-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK15: omp.inner.for.end29: +// CHECK15-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB31]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB32]], align 4 +// CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB31]], align 4 +// CHECK15-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV33]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND35:%.*]] +// CHECK15: omp.inner.for.cond35: +// CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB32]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: [[CMP36:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK15-NEXT: br i1 [[CMP36]], label [[OMP_INNER_FOR_BODY37:%.*]], label [[OMP_INNER_FOR_END43:%.*]] +// CHECK15: omp.inner.for.body37: +// CHECK15-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: [[MUL38:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK15-NEXT: [[ADD39:%.*]] = add nsw i32 0, [[MUL38]] +// CHECK15-NEXT: store i32 [[ADD39]], ptr [[I34]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE40:%.*]] +// CHECK15: omp.body.continue40: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC41:%.*]] +// CHECK15: omp.inner.for.inc41: +// CHECK15-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: [[ADD42:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK15-NEXT: store i32 [[ADD42]], ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND35]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK15: omp.inner.for.end43: +// CHECK15-NEXT: store i32 100, ptr [[I34]], align 4 +// CHECK15-NEXT: ret i32 0 +// diff --git a/clang/test/Parser/cxx-missing-semi-crash.cpp b/clang/test/Parser/cxx-missing-semi-crash.cpp new file mode 100644 index 0000000000000..bed8a2633a618 --- /dev/null +++ b/clang/test/Parser/cxx-missing-semi-crash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s + +// Ensure no crash when DiagnoseMissingSemiAfterTagDefinition encounters an +// annot_template_id not followed by '::'. + +namespace GH207992 { +template void foo(); // expected-note {{'foo' declared here}} +void bar() { + union { + } ::foo; // expected-error {{no template named 'foo' in the global namespace; did you mean simply 'foo'?}} \ + // expected-error {{template specialization requires 'template<>'}} +} +} // namespace N +// expected-error@* {{templates can only be declared in namespace or class scope}} diff --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c index ac8ad64a46950..c7d006171fddb 100644 --- a/clang/test/Preprocessor/x86_target_features.c +++ b/clang/test/Preprocessor/x86_target_features.c @@ -180,6 +180,10 @@ // AVX512BITALG: #define __SSE__ 1 // AVX512BITALG: #define __SSSE3__ 1 +// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512bmm -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512BMM %s + +// AVX512BMM: #define __AVX512BMM__ 1 +// AVX512BMM: #define __AVX512BW__ 1 // RUN: %clang -target i386-unknown-unknown -march=atom -mavx512vbmi -mno-avx512bw -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512VBMINOAVX512BW %s @@ -212,6 +216,11 @@ // AVX512BITALGNOAVX512BW-NOT: #define __AVX512BITALG__ 1 // AVX512BITALGNOAVX512BW-NOT: #define __AVX512BW__ 1 +// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512bmm -mno-avx512bw -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512BMM_NOAVX512BW %s + +// AVX512BMM_NOAVX512BW-NOT: #define __AVX512BMM__ 1 +// AVX512BMM_NOAVX512BW-NOT: #define __AVX512BW__ 1 + // RUN: %clang -target i386-unknown-unknown -march=atom -msse4.2 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=SSE42POPCNT %s // SSE42POPCNT: #define __POPCNT__ 1 diff --git a/clang/test/Sema/attr-cleanup-duplicate.c b/clang/test/Sema/attr-cleanup-duplicate.c new file mode 100644 index 0000000000000..ea596250b612a --- /dev/null +++ b/clang/test/Sema/attr-cleanup-duplicate.c @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s + +// Tests for issue #207785. +// +// Check that a cleanup attribute on an invalid declaration doesn't crash, +// and that we diagnose duplicate cleanup attributes. + +void f1(unsigned *x) {} +void b1() { + __attribute__((cleanup(f1))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f1))) // expected-error {{'cleanup' function 'f1' parameter has type 'unsigned int *' which is incompatible with type 'int *'}} + baz8; // expected-error {{type specifier missing, defaults to 'int'}} + +} + +void b2() { + __attribute__((cleanup(f1))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f1))) // expected-error {{'cleanup' function 'f1' parameter has type 'unsigned int *' which is incompatible with type 'int *'}} + int baz8; +} + +void f2(double *x); +void f3(double *x); +void f4(double *x); +void b3() { + __attribute__((cleanup(f2))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f3))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f4))) + double x; +} + +void b4() { + [[gnu::cleanup(f2)]] // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + [[gnu::cleanup(f3)]] + double x; +} + +void b5() { + [[gnu::cleanup(f2)]] // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f3))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f4))) + double x; +} diff --git a/clang/test/Sema/attr-target.c b/clang/test/Sema/attr-target.c index 036cfc5f53c64..6e9d85b5e1d67 100644 --- a/clang/test/Sema/attr-target.c +++ b/clang/test/Sema/attr-target.c @@ -67,7 +67,7 @@ int __attribute__((target("branch-protection=none"))) birch_tree(void) { return #elifdef __powerpc__ -int __attribute__((target("float128,arch=pwr9"))) foo(void) { return 4; } +int __attribute__((target("float128,cpu=pwr9"))) foo(void) { return 4; } //expected-error@+1 {{'target' attribute takes one argument}} int __attribute__((target())) bar(void) { return 4; } // no warning, tune is supported for PPC @@ -84,7 +84,7 @@ int __attribute__((target("cpu=hiss,cpu=woof"))) pine_tree(void) { return 4; } int __attribute__((target("cpu=pwr9,cpu=pwr10"))) oak_tree(void) { return 4; } //expected-warning@+1 {{unknown tune CPU 'hiss' in the 'target' attribute string; 'target' attribute ignored}} int __attribute__((target("tune=hiss,tune=woof"))) apple_tree(void) { return 4; } -// no warning for invalid target features +//expected-warning@+1 {{unsupported 'woof' in the 'target' attribute string; 'target' attribute ignored}} int __attribute__((target("woof"))) cherry_tree(void) { return 4; } #else diff --git a/clang/test/SemaCXX/typo-correction.cpp b/clang/test/SemaCXX/typo-correction.cpp index d0478706021c7..9f124bec76cc2 100644 --- a/clang/test/SemaCXX/typo-correction.cpp +++ b/clang/test/SemaCXX/typo-correction.cpp @@ -805,3 +805,25 @@ namespace GH206992 { ::~F {}; // expected-error@-1 {{destructor name 'F' does not refer to a template}} }; // namespace GH206992 + +namespace GH207498_1 { + void foo(); + namespace N { + namespace S {} + template void foo() {} + // expected-note@-1 {{'N::foo' declared here}} + }; + template void N::S::foo(); + // expected-error@-1 {{no template named 'foo' in namespace 'GH207498_1::N::S'; did you mean 'N::foo'?}} +} // namespace GH207498_1 + +namespace GH207498_2 { + template void foo() {} + // expected-note@-1 {{'foo' declared here}} + namespace N { + namespace S {} + void foo(); + }; + template void N::S::foo(); + // expected-error@-1 {{no template named 'foo' in namespace 'GH207498_2::N::S'; did you mean simply 'foo'?}} +} // namespace GH207498_2 diff --git a/clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl b/clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl new file mode 100644 index 0000000000000..34f704043e55e --- /dev/null +++ b/clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=RWTexture2D -verify %s + +// RWTexture2D has no mips view (contrast with Texture2D-mips-errors.hlsl, +// which exercises private/protected mips_type on Texture2D). + +TEXTURE t; + +void test_no_mips_member() { + // expected-error@+1 {{no member named 'mips' in 'hlsl::RWTexture2D}} + (void)t.mips; +} + +void test_no_mips_type() { + // expected-error@+1 {{no type named 'mips_type' in 'hlsl::RWTexture2D}} + TEXTURE::mips_type a; + + // expected-error@+1 {{no type named 'mips_slice_type' in 'hlsl::RWTexture2D}} + TEXTURE::mips_slice_type b; +} diff --git a/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl b/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl new file mode 100644 index 0000000000000..61c7497217284 --- /dev/null +++ b/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=RWTexture2D -verify %s + +// SRV-style texture methods are not available on RWTexture2D or RWTexture2DArray (UAV). + +TEXTURE Tex; +SamplerState Samp; +SamplerComparisonState SampCmp; + +void main(float2 uv) { + int2 offset = int2(0, 0); + float compare = 0.5f; + + // expected-error@+1 {{no member named 'SampleLevel' in 'hlsl::RWTexture2D}} + Tex.SampleLevel(Samp, uv, 0.0f); + // expected-error@+1 {{no member named 'SampleBias' in 'hlsl::RWTexture2D}} + Tex.SampleBias(Samp, uv, 0.0f); + // expected-error@+1 {{no member named 'SampleGrad' in 'hlsl::RWTexture2D}} + Tex.SampleGrad(Samp, uv, float2(0), float2(0)); + // expected-error@+1 {{no member named 'SampleCmp' in 'hlsl::RWTexture2D}} + Tex.SampleCmp(SampCmp, uv, compare); + // expected-error@+1 {{no member named 'SampleCmpLevelZero' in 'hlsl::RWTexture2D}} + Tex.SampleCmpLevelZero(SampCmp, uv, compare); + + // expected-error@+1 {{no member named 'Gather' in 'hlsl::RWTexture2D}} + Tex.Gather(Samp, uv); + // expected-error@+1 {{no member named 'GatherRed' in 'hlsl::RWTexture2D}} + Tex.GatherRed(Samp, uv); + // expected-error@+1 {{no member named 'GatherGreen' in 'hlsl::RWTexture2D}} + Tex.GatherGreen(Samp, uv, offset); + // expected-error@+1 {{no member named 'GatherCmp' in 'hlsl::RWTexture2D}} + Tex.GatherCmp(SampCmp, uv, compare); + + // expected-error@+1 {{no member named 'CalculateLevelOfDetail' in 'hlsl::RWTexture2D}} + (void)Tex.CalculateLevelOfDetail(Samp, uv); + // expected-error@+1 {{no member named 'CalculateLevelOfDetailUnclamped' in 'hlsl::RWTexture2D}} + (void)Tex.CalculateLevelOfDetailUnclamped(Samp, uv); +} diff --git a/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl b/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl index c6886f975ea59..6a6c2b1e2da4e 100644 --- a/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl +++ b/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -DTEXTURE=Texture2D -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -DTEXTURE=Texture2DArray -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -DTEXTURE=RWTexture2D -verify %s -Texture2D tex; +TEXTURE tex; void main() { uint u_w, u_h, u_l; diff --git a/clang/test/SemaHLSL/Texture2D-Load-errors.hlsl b/clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl similarity index 52% rename from clang/test/SemaHLSL/Texture2D-Load-errors.hlsl rename to clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl index 9027c2ea144b8..88e1f81d07094 100644 --- a/clang/test/SemaHLSL/Texture2D-Load-errors.hlsl +++ b/clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl @@ -1,6 +1,18 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -verify %s - -Texture2D t; +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=Texture2D -DARRAYED=0 -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=Texture2DArray -DARRAYED=1 -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=RWTexture2D -DARRAYED=0 -verify %s + +#if ARRAYED +#define ITY int4 +#define FTY float4 +#define ZEROS 0, 0 +#else +#define ITY int3 +#define FTY float3 +#define ZEROS 0 +#endif + +TEXTURE t; float4 test_too_few_args() { return t.Load(); // expected-error {{no matching member function for call to 'Load'}} @@ -9,35 +21,38 @@ float4 test_too_few_args() { } float4 test_too_many_args(int2 loc) { - return t.Load(int3(loc, 0), int2(1, 1), 1); // expected-error {{no matching member function for call to 'Load'}} + return t.Load(ITY(loc, ZEROS), int2(1, 1), 1); // expected-error {{no matching member function for call to 'Load'}} // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 3 were provided}} // expected-note@*:* {{candidate function not viable: requires single argument 'Location', but 3 arguments were provided}} } float4 test_invalid_coord_type(float2 loc) { - return t.Load(float3(loc, 0)); // expected-warning {{implicit conversion turns floating-point number into integer: 'float3' (aka 'vector') to 'vector'}} + return t.Load(FTY(loc, ZEROS)); // expected-warning {{implicit conversion turns floating-point number into integer: }} } float4 test_invalid_offset_type(int2 loc, float2 offset) { - return t.Load(int3(loc, 0), offset); // expected-warning {{implicit conversion turns floating-point number into integer: 'float2' (aka 'vector') to 'vector'}} + return t.Load(ITY(loc, ZEROS), offset); // expected-warning {{implicit conversion turns floating-point number into integer: 'float2' (aka 'vector') to 'vector' (vector of 2 'int' values)}} } float4 test_invalid_location_count(int2 loc) { return t.Load(loc); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: no known conversion from 'int2' (aka 'vector') to 'vector' (vector of 3 'int' values) for 1st argument}} + // expected-note@*:* {{candidate function not viable: no known conversion from 'int2' (aka 'vector') to }} // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}} } float4 test_truncated_location_count(int4 loc) { +#if ARRAYED + return t.Load(loc); // no warning expected for array textures which take an int4 argument +#else return t.Load(loc); // expected-warning {{implicit conversion truncates vector: 'int4' (aka 'vector') to 'vector' (vector of 3 'int' values)}} +#endif } -float4 test_splatted_offset_count(int3 loc, int offset) { +float4 test_splatted_offset_count(ITY loc, int offset) { // No errors expected. The vector will be generated by splatting `offset`. return t.Load(loc, offset); } - float4 test_truncated_offset_count(int2 loc, int3 offset) { - return t.Load(int3(loc, 0), offset); // expected-warning {{implicit conversion truncates vector: 'int3' (aka 'vector') to 'vector' (vector of 2 'int' values)}} + return t.Load(ITY(loc, ZEROS), offset); // expected-warning {{implicit conversion truncates vector: 'int3' (aka 'vector') to 'vector' (vector of 2 'int' values)}} } diff --git a/clang/test/SemaHLSL/Resources/resource_params_noinline.hlsl b/clang/test/SemaHLSL/Resources/resource_params_noinline.hlsl new file mode 100644 index 0000000000000..fbe0a7b070be4 --- /dev/null +++ b/clang/test/SemaHLSL/Resources/resource_params_noinline.hlsl @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -fsyntax-only -finclude-default-header %s -verify + +// expected-error@+2 {{resource type 'RWBuffer' cannot be used as a parameter of a noinline function}} +// expected-note@+1 {{attribute is here}} +__attribute__((noinline)) float resource_param(RWBuffer A) {} + +// expected-error@+2 {{resource type 'RWBuffer[4]' cannot be used as a parameter of a noinline function}} +// expected-note@+1 {{attribute is here}} +__attribute__((noinline)) float resource_array_param(RWBuffer A[4]) {} + +struct MyStruct { + RWBuffer A; +}; +// expected-error@+2 {{resource type 'MyStruct' cannot be used as a parameter of a noinline function}} +// expected-note@+1 {{attribute is here}} +__attribute__((noinline)) float resource_struct_param(MyStruct S) {} + +// expected-error@+2 {{resource type 'RWByteAddressBuffer' cannot be used as a parameter of a noinline function}} +// expected-note@+1 {{attribute is here}} +__attribute__((noinline)) void no_prior_use(RWByteAddressBuffer A) {} diff --git a/clang/test/SemaHLSL/Resources/unbounded_resource_arrays.hlsl b/clang/test/SemaHLSL/Resources/unbounded_resource_arrays.hlsl index b65deeda9a4ff..0dc09e2a3c272 100644 --- a/clang/test/SemaHLSL/Resources/unbounded_resource_arrays.hlsl +++ b/clang/test/SemaHLSL/Resources/unbounded_resource_arrays.hlsl @@ -1,21 +1,29 @@ -// RUN: not %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -finclude-default-header --o - %s -verify - -// unbounded resource array at a global scope -RWBuffer unbounded_array[]; // no_error - -// expected-error@+1 {{incomplete resource array in a function parameter}} -void foo(RWBuffer array_arg[]) {} - -RWBuffer A, B; - -[numthreads(4,1,1)] -void main() { - // expected-error@+1{{definition of variable with array type needs an explicit size or an initializer}} - RWBuffer res_local_array1[]; - - // expected-error@+1{{array initializer must be an initialzer list}} - RWBuffer res_local_array2[] = unbounded_array; - - // local incomplete resource array with initializer - RWBuffer res_local_array3[] = { A, B }; // no error -} +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -fsyntax-only -finclude-default-header %s -verify + +// unbounded resource array parameter whose resource type has not been used earlier +// expected-error@+1 {{incomplete resource array in a function parameter}} +void no_prior_use(RWByteAddressBuffer array_arg[]) {} + +// unbounded resource array at a global scope +RWBuffer unbounded_array[]; // no error + +// expected-error@+1 {{incomplete resource array in a function parameter}} +void foo(RWBuffer array_arg[]) {} + +// a non-resource incomplete-array parameter should not error +struct S; +void non_resource(S array_arg[]); // no error + +RWBuffer A, B; + +[numthreads(4,1,1)] +void main() { + // expected-error@+1{{definition of variable with array type needs an explicit size or an initializer}} + RWBuffer res_local_array1[]; + + // expected-error@+1{{array initializer must be an initializer list}} + RWBuffer res_local_array2[] = unbounded_array; + + // local incomplete resource array with initializer + RWBuffer res_local_array3[] = { A, B }; // no error +} diff --git a/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl b/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl deleted file mode 100644 index 36427aab0e604..0000000000000 --- a/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -verify %s - -Texture2DArray t; - -float4 test_too_few_args() { - return t.Load(); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: requires single argument 'Location', but no arguments were provided}} - // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 0 were provided}} -} - -float4 test_too_many_args(int3 loc) { - return t.Load(int4(loc, 0), int2(1, 1), 1); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 3 were provided}} - // expected-note@*:* {{candidate function not viable: requires single argument 'Location', but 3 arguments were provided}} -} - -float4 test_invalid_coord_type(float3 loc) { - return t.Load(float4(loc, 0)); // expected-warning {{implicit conversion turns floating-point number into integer: 'float4' (aka 'vector') to 'vector'}} -} - -float4 test_invalid_offset_type(int3 loc, float2 offset) { - return t.Load(int4(loc, 0), offset); // expected-warning {{implicit conversion turns floating-point number into integer: 'float2' (aka 'vector') to 'vector'}} -} - -float4 test_invalid_location_count(int2 loc) { - return t.Load(loc); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: no known conversion from 'int2' (aka 'vector') to 'vector' (vector of 4 'int' values) for 1st argument}} - // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}} -} - -float4 test_short_location_count(int3 loc) { - return t.Load(loc); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: no known conversion from 'int3' (aka 'vector') to 'vector' (vector of 4 'int' values) for 1st argument}} - // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}} -} - -float4 test_splatted_offset_count(int4 loc, int offset) { - // No errors expected. The vector will be generated by splatting `offset`. - return t.Load(loc, offset); -} - -float4 test_truncated_offset_count(int3 loc, int3 offset) { - return t.Load(int4(loc, 0), offset); // expected-warning {{implicit conversion truncates vector: 'int3' (aka 'vector') to 'vector' (vector of 2 'int' values)}} -} diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-s-buffer-load-error.cl b/clang/test/SemaOpenCL/builtins-amdgcn-s-buffer-load-error.cl new file mode 100644 index 0000000000000..3c1694aa54500 --- /dev/null +++ b/clang/test/SemaOpenCL/builtins-amdgcn-s-buffer-load-error.cl @@ -0,0 +1,125 @@ +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu verde -S -verify -o - %s +// REQUIRES: amdgpu-registered-target + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +typedef int v4i32 __attribute__((ext_vector_type(4))); +typedef int v2i32 __attribute__((ext_vector_type(2))); +typedef int v3i32 __attribute__((ext_vector_type(3))); +typedef int v8i32 __attribute__((ext_vector_type(8))); +typedef int v16i32 __attribute__((ext_vector_type(16))); +typedef float v2f32 __attribute__((ext_vector_type(2))); +typedef float v3f32 __attribute__((ext_vector_type(3))); +typedef float v4f32 __attribute__((ext_vector_type(4))); +typedef float v8f32 __attribute__((ext_vector_type(8))); +typedef float v16f32 __attribute__((ext_vector_type(16))); +typedef char v2i8 __attribute__((ext_vector_type(2))); +typedef char v3i8 __attribute__((ext_vector_type(3))); +typedef char v4i8 __attribute__((ext_vector_type(4))); +typedef half v2f16 __attribute__((ext_vector_type(2))); +typedef half v3f16 __attribute__((ext_vector_type(3))); +typedef half v4f16 __attribute__((ext_vector_type(4))); + +int test_amdgcn_s_buffer_load_i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_i32' must be a constant integer}} +} + +v2i32 test_amdgcn_s_buffer_load_v2i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v2i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v2i32' must be a constant integer}} +} + +v3i32 test_amdgcn_s_buffer_load_v3i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v3i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v3i32' must be a constant integer}} +} + +v4i32 test_amdgcn_s_buffer_load_v4i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v4i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v4i32' must be a constant integer}} +} + +v8i32 test_amdgcn_s_buffer_load_v8i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v8i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v8i32' must be a constant integer}} +} + +v16i32 test_amdgcn_s_buffer_load_v16i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v16i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v16i32' must be a constant integer}} +} + +float test_amdgcn_s_buffer_load_f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_f32' must be a constant integer}} +} + +v2f32 test_amdgcn_s_buffer_load_v2f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v2f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v2f32' must be a constant integer}} +} + +v3f32 test_amdgcn_s_buffer_load_v3f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v3f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v3f32' must be a constant integer}} +} + +v4f32 test_amdgcn_s_buffer_load_v4f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v4f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v4f32' must be a constant integer}} +} + +v8f32 test_amdgcn_s_buffer_load_v8f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v8f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v8f32' must be a constant integer}} +} + +v16f32 test_amdgcn_s_buffer_load_v16f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v16f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v16f32' must be a constant integer}} +} + +char test_amdgcn_s_buffer_load_i8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_i8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_i8' must be a constant integer}} +} + +unsigned char test_amdgcn_s_buffer_load_u8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_u8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_u8' must be a constant integer}} +} + +short test_amdgcn_s_buffer_load_i16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_i16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_i16' must be a constant integer}} +} + +unsigned short test_amdgcn_s_buffer_load_u16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_u16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_u16' must be a constant integer}} +} + +v2i8 test_amdgcn_s_buffer_load_v2i8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v2i8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v2i8' must be a constant integer}} +} + +v3i8 test_amdgcn_s_buffer_load_v3i8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v3i8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v3i8' must be a constant integer}} +} + +v4i8 test_amdgcn_s_buffer_load_v4i8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v4i8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v4i8' must be a constant integer}} +} + +half test_amdgcn_s_buffer_load_f16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_f16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_f16' must be a constant integer}} +} + +v2f16 test_amdgcn_s_buffer_load_v2f16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v2f16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v2f16' must be a constant integer}} +} + +v3f16 test_amdgcn_s_buffer_load_v3f16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v3f16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v3f16' must be a constant integer}} +} + +v4f16 test_amdgcn_s_buffer_load_v4f16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v4f16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v4f16' must be a constant integer}} +} + +int test_amdgcn_s_buffer_load_i32_too_few_args(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, 0); //expected-error{{too few arguments to function call, expected 3, have 2}} +} + +int test_amdgcn_s_buffer_load_i32_too_many_args(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, 0, 0, 0); //expected-error{{too many arguments to function call, expected 3, have 4}} +} + +int test_amdgcn_s_buffer_load_i32_wrong_rsrc_type(v4i32 rsrc) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, 0, 0); //expected-error{{passing '__private v4i32' (vector of 4 'int' values) to parameter of incompatible type '__amdgpu_buffer_rsrc_t'}} +} diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp index 6c41853cf3b4f..60ab6a4939282 100644 --- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp +++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp @@ -915,7 +915,7 @@ namespace FuncTemplateInClass { requires C auto TplClass<0>::buggy() -> void {} // expected-error@-1 {{out-of-line definition of 'buggy' does not match any declaration}} - } //namespace t1 + } // namespace t1 namespace t2 { template struct TplClass { // expected-note {{defined here}} template @@ -928,7 +928,7 @@ namespace FuncTemplateInClass { requires C auto TplClass<0>::buggy() -> void {} // expected-error@-1 {{out-of-line definition of 'buggy' does not match any declaration}} - } //namespace t2 + } // namespace t2 } // namespace FuncTemplateInClass namespace GH139476 { diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index 6f7f00bf12e61..f2478e1a22a6a 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -997,7 +997,7 @@ template concept True = true; template -concept False = false; // expected-note 9 {{'false' evaluated to false}} +concept False = false; // expected-note 8 {{'false' evaluated to false}} template concept Irrelevant = false; @@ -1009,8 +1009,8 @@ concept ErrorRequires = requires(ErrorRequires auto x) { x; }; //#GH54678-ill-fo // expected-note@-1 {{declared here}} template concept C1 = C1 && [](C1 auto) -> C1 auto {}; -//expected-error@-1 4{{a concept definition cannot refer to itself}} \ -//expected-note@-1 4{{declared here}} +//expected-error@-1 {{a concept definition cannot refer to itself}} \ +//expected-note@-1 {{declared here}} template void aaa(T t) // expected-note {{candidate template ignored: constraints not satisfied}} requires (False || False) || False {} // expected-note 3 {{'int' does not satisfy 'False'}} @@ -1023,15 +1023,15 @@ requires (Irrelevant || True) && False {} // expected-note {{'int' does template void eee(T t) // expected-note {{candidate template ignored: constraints not satisfied}} requires (Irrelevant || Irrelevant || True) && False {} // expected-note {{'long' does not satisfy 'False'}} -template void fff(T t) // expected-note {{candidate template ignored: constraints not satisfied}} -requires((ErrorRequires || False || True) && False) {} // expected-note {{because 'unsigned long' does not satisfy 'False'}} +template void fff(T t) +requires((ErrorRequires || False || True) && False) {} void test() { aaa(42); // expected-error {{no matching function}} bbb(42L); // expected-error{{no matching function}} ccc(42UL); // expected-error {{no matching function}} ddd(42); // expected-error {{no matching function}} eee(42L); // expected-error {{no matching function}} - fff(42UL); // expected-error {{no matching function}} + fff(42UL); } } @@ -2064,3 +2064,19 @@ auto x = quantity{}, int>{}; } // namespace CannotResolve1 } // namespace GH175831 + + +namespace GH206336 { +class Dim; +struct S; +template concept foo = true; +template concept SS = false; // expected-note {{because 'false' evaluated to false}} +template concept _Dim = _Dim; // expected-error {{a concept definition cannot refer to itself}} \ + // expected-note {{declared here}} +template E> auto bar(Dim, E) {}; // expected-note {{candidate template ignored: constraints not satisfied}} \ + // expected-note {{because 'GH206336::S' does not satisfy 'SS'}} + +void baz() { + auto qux = bar(true, [] {}); // expected-error {{no matching function for call to 'bar'}} +} +} diff --git a/clang/tools/scan-build-py/lib/libscanbuild/__init__.py b/clang/tools/scan-build-py/lib/libscanbuild/__init__.py index ba1600866c4d7..b9ae777bfae73 100644 --- a/clang/tools/scan-build-py/lib/libscanbuild/__init__.py +++ b/clang/tools/scan-build-py/lib/libscanbuild/__init__.py @@ -196,9 +196,8 @@ def run_compiler(executable): function(result, call) except: logging.exception("Compiler wrapper failed complete.") - finally: - # Always return the real compiler exit code. - return result + # Always return the real compiler exit code. + return result def wrapper_environment(args): diff --git a/clang/unittests/Frontend/ASTUnitTest.cpp b/clang/unittests/Frontend/ASTUnitTest.cpp index bf9e4e184b5db..08dcd80a414ef 100644 --- a/clang/unittests/Frontend/ASTUnitTest.cpp +++ b/clang/unittests/Frontend/ASTUnitTest.cpp @@ -38,13 +38,15 @@ class ASTUnitTest : public ::testing::Test { std::shared_ptr CInvok; std::shared_ptr PCHContainerOps; - std::unique_ptr createASTUnit(bool isVolatile) { + std::unique_ptr + createASTUnit(bool isVolatile, ArrayRef ExtraArgs = {}) { EXPECT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "cpp", FD, InputFileName)); input_file = std::make_unique(InputFileName, FD); input_file->os() << ""; - const char *Args[] = {"clang", "-xc++", InputFileName.c_str()}; + SmallVector Args{"clang", "-xc++", InputFileName.c_str()}; + append_range(Args, ExtraArgs); auto VFS = llvm::vfs::getRealFileSystem(); Diags = CompilerInstance::createDiagnostics(*VFS, *DiagOpts); @@ -109,6 +111,42 @@ TEST_F(ASTUnitTest, SaveLoadPreservesLangOptionsInPrintingPolicy) { EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams); } +TEST_F(ASTUnitTest, SaveLoadPreservesCodeGenOptions) { + // Check that the CodeGenOptions are preserved when saving and loading an + // ASTUnit from a file. + + { + std::unique_ptr AST = createASTUnit(false); + if (!AST) + FAIL() << "failed to create ASTUnit"; + EXPECT_EQ(AST->getCodeGenOpts().OptimizationLevel, 0u); + } + + std::unique_ptr AST = createASTUnit(false, {"-O3"}); + if (!AST) + FAIL() << "failed to create ASTUnit"; + EXPECT_EQ(AST->getCodeGenOpts().OptimizationLevel, 3u); + + llvm::SmallString<256> ASTFileName; + ASSERT_FALSE( + llvm::sys::fs::createTemporaryFile("ast-unit", "ast", FD, ASTFileName)); + ToolOutputFile ast_file(ASTFileName, FD); + AST->Save(ASTFileName.str()); + + EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName)); + HeaderSearchOptions HSOpts; + + std::unique_ptr AU = ASTUnit::LoadFromASTFile( + ASTFileName, PCHContainerOps->getRawReader(), ASTUnit::LoadEverything, + llvm::vfs::getRealFileSystem(), DiagOpts, Diags, FileSystemOptions(), + HSOpts); + + if (!AU) + FAIL() << "failed to load ASTUnit"; + + EXPECT_EQ(AU->getCodeGenOpts().OptimizationLevel, 3u); +} + TEST_F(ASTUnitTest, GetBufferForFileMemoryMapping) { std::unique_ptr AST = createASTUnit(true); diff --git a/clang/unittests/ScalableStaticAnalysis/CMakeLists.txt b/clang/unittests/ScalableStaticAnalysis/CMakeLists.txt index 972287132b36d..08f82876aabf1 100644 --- a/clang/unittests/ScalableStaticAnalysis/CMakeLists.txt +++ b/clang/unittests/ScalableStaticAnalysis/CMakeLists.txt @@ -27,6 +27,7 @@ add_distinct_clang_unittest(ClangScalableAnalysisTests Serialization/JSONFormatTest/TUSummaryTest.cpp SourceTransformation/EmitterTest.cpp SourceTransformation/RegistryTest.cpp + SourceTransformation/SARIFFormatTest.cpp SourceTransformation/YAMLFormatTest.cpp SummaryData/SummaryDataTest.cpp SummaryNameTest.cpp diff --git a/clang/unittests/ScalableStaticAnalysis/SourceTransformation/SARIFFormatTest.cpp b/clang/unittests/ScalableStaticAnalysis/SourceTransformation/SARIFFormatTest.cpp new file mode 100644 index 0000000000000..1870f834178cc --- /dev/null +++ b/clang/unittests/ScalableStaticAnalysis/SourceTransformation/SARIFFormatTest.cpp @@ -0,0 +1,185 @@ +//===- SARIFFormatTest.cpp ------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/Sarif.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/Version.h" +#include "clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/JSON.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/VirtualFileSystem.h" +#include "llvm/Testing/Support/Error.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace clang; +using namespace ssaf; + +namespace { + +struct TempPath { + SmallString<128> Path; + + TempPath(StringRef Suffix) { + sys::fs::createUniquePath("ssaf-sarif-%%%%%%." + Suffix, Path, + /*MakeAbsolute=*/true); + } + ~TempPath() { sys::fs::remove(Path); } +}; + +class SARIFFormatTest : public ::testing::Test { +protected: + SARIFFormatTest() + : Diags(DiagnosticIDs::create(), DiagOpts, new IgnoringDiagConsumer()), + VFS(makeIntrusiveRefCnt()), + FileMgr(FileSystemOptions(), VFS), SourceMgr(Diags, FileMgr) {} + + json::Value writeAndParse(const ReportDocument &Doc) { + TempPath TP("sarif"); + EXPECT_THAT_ERROR(writeSARIFTransformationReport(Doc, TP.Path), + Succeeded()); + auto BufferOrErr = MemoryBuffer::getFile(TP.Path); + EXPECT_TRUE(static_cast(BufferOrErr)); + auto ParsedOrErr = json::parse((*BufferOrErr)->getBuffer()); + EXPECT_THAT_EXPECTED(ParsedOrErr, Succeeded()); + return std::move(*ParsedOrErr); + } + + DiagnosticOptions DiagOpts; + DiagnosticsEngine Diags; + IntrusiveRefCntPtr VFS; + FileManager FileMgr; + SourceManager SourceMgr; +}; + +TEST_F(SARIFFormatTest, ToolDriverNameAndVersion) { + ReportDocument Doc{"my-transformation", SourceMgr, {}}; + json::Value V = writeAndParse(Doc); + + const json::Object *Root = V.getAsObject(); + ASSERT_NE(Root, nullptr); + const json::Array *Runs = Root->getArray("runs"); + ASSERT_NE(Runs, nullptr); + ASSERT_EQ(Runs->size(), 1u); + const json::Object *Driver = + (*Runs)[0].getAsObject()->getObject("tool")->getObject("driver"); + ASSERT_NE(Driver, nullptr); + EXPECT_EQ(*Driver->getString("name"), "clang-ssaf"); + EXPECT_NE(Driver->getString("fullName")->find("my-transformation"), + StringRef::npos); + EXPECT_EQ(*Driver->getString("version"), CLANG_VERSION_STRING); +} + +TEST_F(SARIFFormatTest, LevelMapping) { + ReportDocument Doc{"t", + SourceMgr, + { + {"r-note", clang::SarifResultLevel::Note, {}, "n"}, + {"r-warn", clang::SarifResultLevel::Warning, {}, "w"}, + {"r-error", clang::SarifResultLevel::Error, {}, "e"}, + {"r-none", clang::SarifResultLevel::None, {}, "x"}, + }}; + json::Value V = writeAndParse(Doc); + + const json::Array *Results = + V.getAsObject()->getArray("runs")->front().getAsObject()->getArray( + "results"); + ASSERT_NE(Results, nullptr); + ASSERT_EQ(Results->size(), 4u); + EXPECT_EQ(*(*Results)[0].getAsObject()->getString("level"), "note"); + EXPECT_EQ(*(*Results)[1].getAsObject()->getString("level"), "warning"); + EXPECT_EQ(*(*Results)[2].getAsObject()->getString("level"), "error"); + EXPECT_EQ(*(*Results)[3].getAsObject()->getString("level"), "none"); +} + +TEST_F(SARIFFormatTest, InvalidRangeOmitsLocations) { + ReportDocument Doc{ + "t", + SourceMgr, + {{"r", clang::SarifResultLevel::Note, clang::CharSourceRange{}, "msg"}}}; + json::Value V = writeAndParse(Doc); + const json::Object *Result = V.getAsObject() + ->getArray("runs") + ->front() + .getAsObject() + ->getArray("results") + ->front() + .getAsObject(); + EXPECT_EQ(Result->get("locations"), nullptr); +} + +TEST_F(SARIFFormatTest, EmptyResultsValidDocument) { + ReportDocument Doc{"t", SourceMgr, {}}; + json::Value V = writeAndParse(Doc); + const json::Object *Run = + V.getAsObject()->getArray("runs")->front().getAsObject(); + // SARIF allows the results array to be absent or empty for an empty run. + if (const json::Array *Results = Run->getArray("results")) + EXPECT_TRUE(Results->empty()); +} + +TEST_F(SARIFFormatTest, NoFixKey) { + ReportDocument Doc{ + "t", SourceMgr, {{"r", clang::SarifResultLevel::Warning, {}, "msg"}}}; + json::Value V = writeAndParse(Doc); + const json::Object *Result = V.getAsObject() + ->getArray("runs") + ->front() + .getAsObject() + ->getArray("results") + ->front() + .getAsObject(); + EXPECT_EQ(Result->get("fix"), nullptr); + EXPECT_EQ(Result->get("fixes"), nullptr); +} + +TEST_F(SARIFFormatTest, EmptyRuleIdAccepted) { + ReportDocument Doc{ + "t", SourceMgr, {{"", clang::SarifResultLevel::Note, {}, "m"}}}; + json::Value V = writeAndParse(Doc); + const json::Object *Result = V.getAsObject() + ->getArray("runs") + ->front() + .getAsObject() + ->getArray("results") + ->front() + .getAsObject(); + ASSERT_NE(Result->getString("ruleId"), std::nullopt); + EXPECT_EQ(*Result->getString("ruleId"), ""); +} + +TEST_F(SARIFFormatTest, DistinctRuleIdsDeduplicated) { + ReportDocument Doc{"t", + SourceMgr, + { + {"a", clang::SarifResultLevel::Note, {}, "m1"}, + {"b", clang::SarifResultLevel::Note, {}, "m2"}, + {"a", clang::SarifResultLevel::Note, {}, "m3"}, + }}; + json::Value V = writeAndParse(Doc); + const json::Array *Rules = V.getAsObject() + ->getArray("runs") + ->front() + .getAsObject() + ->getObject("tool") + ->getObject("driver") + ->getArray("rules"); + ASSERT_NE(Rules, nullptr); + EXPECT_EQ(Rules->size(), 2u); +} + +} // namespace diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index d1a260b07a0fa..af91ac559d274 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -21439,7 +21439,7 @@

C++ defect report implementation status

3089 [dcl.init.general] WP - const-default-constructible improperly handles std::meta::info + const-default-constructible improperly handles std::meta::info Unknown @@ -22149,38 +22149,38 @@

C++ defect report implementation status

Ambiguous lookup for type aliases in reflection Not resolved - + 3191 [dcl.ref] - open + tentatively ready Reference collapsing with pack indexing and splicing - Not resolved + Unknown 3192 [class.local] - open + tentatively ready Out-of-line definition of an enum member of a local class Not resolved 3193 [dcl.friend] - open + tentatively ready Missing restrictions and effects for friend declarations Not resolved 3194 [lex.pptoken] - open + tentatively ready Lexing of <=> Not resolved 3195 [expr.const.core] - open + tentatively ready Starting the lifetime of a runtime object during constant evaluation Not resolved @@ -22194,7 +22194,7 @@

C++ defect report implementation status

3197 [diff.basic] - open + review Relaxed requirements for integer representations Not resolved @@ -22208,9 +22208,58 @@

C++ defect report implementation status

3199 [cpp.predefined] - open + tentatively ready Missing predefined macros for chart16_t and char32_t Not resolved + + + 3200 + [dcl.type.cv] + tentatively ready + Qualified pointer pointing to unqualified object + Not resolved + + + 3201 + [dcl.init.general] + tentatively ready + Zero- and default-initialization of cv-qualified std::meta::info + Not resolved + + + 3202 + [basic.fundamental] + open + Status of const std::meta::info + Not resolved + + + 3203 + [dcl.init.general] + open + Initialization of signed or unsigned char arrays from string-literal + Not resolved + + + 3204 + [expr.call] + open + Restrictions on arguments for ellipsis parameter + Not resolved + + + 3205 + [lex.pptoken] + review + Prefer header-name over user-defined-string-literal + Not resolved + + + 3206 + [class.local] + open + Scattered definition of "local class" + Not resolved diff --git a/cmake/Modules/GetTripleCMakeSystemName.cmake b/cmake/Modules/GetTripleCMakeSystemName.cmake deleted file mode 100644 index 6cd8d3c59324e..0000000000000 --- a/cmake/Modules/GetTripleCMakeSystemName.cmake +++ /dev/null @@ -1,89 +0,0 @@ -#===--------------------------------------------------------------------===// -# -# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for details. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# -#===--------------------------------------------------------------------===// - -# Extract the OS component from a target triple and map it to the -# corresponding CMake system name. -# -# Usage: -# get_triple_cmake_system_name( ) -# -# Parses the triple (arch-vendor-os[-env]) and sets to the -# CMake-style system name (e.g. "Darwin", "Linux", "Windows"). -# Unrecognized OS values are mapped to "Generic". This expects a -# normalized triple. - -function(get_triple_cmake_system_name triple out_var) - string(REPLACE "-" ";" _components "${triple}") - list(LENGTH _components _len) - if(_len LESS 3) - set(${out_var} "${CMAKE_HOST_SYSTEM_NAME}" PARENT_SCOPE) - return() - endif() - - list(GET _components 1 _vendor) - list(GET _components 2 _os) - set(_env "") - if(_len GREATER_EQUAL 4) - list(GET _components 3 _env) - endif() - - # Check the special environment components first, since it can - # override the usual OS mapping. - if("${_env}" MATCHES "^android") - set(${out_var} "Android" PARENT_SCOPE) - elseif("${_env}" MATCHES "^cygnus") - set(${out_var} "CYGWIN" PARENT_SCOPE) - elseif("${_os}" MATCHES "^darwin|^macos") - set(${out_var} "Darwin" PARENT_SCOPE) - elseif("${_os}" MATCHES "^ios") - set(${out_var} "iOS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^tvos") - set(${out_var} "tvOS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^watchos") - set(${out_var} "watchOS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^xros|^visionos") - set(${out_var} "visionOS" PARENT_SCOPE) - elseif("${_vendor}" STREQUAL "apple") - # Catch-all for other Apple triples (e.g. driverkit, bridgeos). - set(${out_var} "Darwin" PARENT_SCOPE) - elseif("${_os}" MATCHES "^linux") - set(${out_var} "Linux" PARENT_SCOPE) - elseif("${_os}" MATCHES "^windows") - set(${out_var} "Windows" PARENT_SCOPE) - elseif("${_os}" MATCHES "^freebsd|^kfreebsd") - set(${out_var} "FreeBSD" PARENT_SCOPE) - elseif("${_os}" MATCHES "^netbsd") - set(${out_var} "NetBSD" PARENT_SCOPE) - elseif("${_os}" MATCHES "^openbsd") - set(${out_var} "OpenBSD" PARENT_SCOPE) - elseif("${_os}" MATCHES "^dragonfly") - set(${out_var} "DragonFly" PARENT_SCOPE) - elseif("${_os}" MATCHES "^solaris") - set(${out_var} "SunOS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^aix") - set(${out_var} "AIX" PARENT_SCOPE) - elseif("${_os}" MATCHES "^fuchsia") - set(${out_var} "Fuchsia" PARENT_SCOPE) - elseif("${_os}" MATCHES "^haiku") - set(${out_var} "Haiku" PARENT_SCOPE) - elseif("${_os}" MATCHES "^emscripten") - set(${out_var} "Emscripten" PARENT_SCOPE) - elseif("${_os}" MATCHES "^wasi") - set(${out_var} "WASI" PARENT_SCOPE) - elseif("${_os}" MATCHES "^rtems") - set(${out_var} "RTEMS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^zos") - set(${out_var} "OS390" PARENT_SCOPE) - elseif("${_os}" MATCHES "^hurd") - set(${out_var} "GNU" PARENT_SCOPE) - elseif("${_os}" MATCHES "^serenity") - set(${out_var} "SerenityOS" PARENT_SCOPE) - else() - set(${out_var} "Generic" PARENT_SCOPE) - endif() -endfunction() diff --git a/cmake/Modules/NormalizeTriple.cmake b/cmake/Modules/NormalizeTriple.cmake deleted file mode 100644 index 08f09a22bdbb0..0000000000000 --- a/cmake/Modules/NormalizeTriple.cmake +++ /dev/null @@ -1,36 +0,0 @@ -#===--------------------------------------------------------------------===// -# -# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for details. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# -#===--------------------------------------------------------------------===// - -# Normalize a target triple using clang's -print-target-triple. -# -# Usage: -# normalize_triple( ) -# -# Runs --target= -print-target-triple to produce a -# canonical triple. If the compiler invocation fails (e.g. the compiler -# is not clang), is returned unchanged. - -function(normalize_triple compiler triple out_var) - set(_prefix "") - if(CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC") - set(_prefix "/clang:") - endif() - execute_process( - COMMAND "${compiler}" "${_prefix}--target=${triple}" "${_prefix}-print-target-triple" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _output - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET) - if(_result EQUAL 0 AND _output) - set(${out_var} "${_output}" PARENT_SCOPE) - else() - # TODO(#97876): Report an error. - message(WARNING "Failed to execute `${compiler} ${_prefix}--target=${triple} ${_prefix}-print-target-triple` to normalize target triple.") - set(${out_var} "${triple}" PARENT_SCOPE) - endif() -endfunction() diff --git a/compiler-rt/lib/scudo/standalone/tsd_shared.h b/compiler-rt/lib/scudo/standalone/tsd_shared.h index 5f9092b36d42a..859f42eb373b2 100644 --- a/compiler-rt/lib/scudo/standalone/tsd_shared.h +++ b/compiler-rt/lib/scudo/standalone/tsd_shared.h @@ -141,16 +141,14 @@ struct TSDRegistrySharedT { ALWAYS_INLINE TSD *getTSDAndLock() NO_THREAD_SAFETY_ANALYSIS { TSD *TSD = getCurrentTSD(); DCHECK(TSD); - // Try to lock the currently associated context. - if (TSD->tryLock()) - return TSD; - // If that fails, go down the slow path. if (TSDsArraySize == 1U) { - // Only 1 TSD, not need to go any further. - // The compiler will optimize this one way or the other. + // Only 1 TSD, lock and return. TSD->lock(); return TSD; } + + if (TSD->tryLock()) + return TSD; return getTSDSlow(TSD); } @@ -176,6 +174,7 @@ struct TSDRegistrySharedT { // Requires a lock to avoid multiple threads trying to set the TSDs at once. bool setNumberOfTSDs(u32 N) REQUIRES(Mutex) { + DCHECK_GT(N, 0); const u32 TotalTSDs = atomic_load_relaxed(&NumberOfTSDs); // In order to avoid needing locks for these values, the number of TSDs // can never be decreased. @@ -234,7 +233,7 @@ struct TSDRegistrySharedT { // capability. NOINLINE TSD *getTSDSlow(TSD *CurrentTSD) { const u32 TotalTSDs = atomic_load_relaxed(&NumberOfTSDs); - if (UNLIKELY(TotalTSDs <= 1U)) { + if (UNLIKELY(TotalTSDs == 1U)) { CurrentTSD->lock(); return CurrentTSD; } diff --git a/flang/include/flang/Optimizer/Analysis/AliasAnalysis.h b/flang/include/flang/Optimizer/Analysis/AliasAnalysis.h index 832634a708dba..32d95d3e09677 100644 --- a/flang/include/flang/Optimizer/Analysis/AliasAnalysis.h +++ b/flang/include/flang/Optimizer/Analysis/AliasAnalysis.h @@ -19,7 +19,9 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" +#include #include +#include namespace fir { @@ -351,10 +353,39 @@ struct AliasAnalysis { /// snapshots are not collected, and getSource performs only the /// SourceKind/origin classification without that bookkeeping side /// effect. + /// + /// When source caching is enabled (see enableSourceCache()), the result is + /// memoized keyed on (value, flags), and recursive sub-queries share the + /// same cache. The cache is a frozen snapshot with no automatic + /// invalidation: it is only valid while the IR reachable from the queried + /// values is not mutated in a way that would change the source. It lives no + /// longer than this AliasAnalysis instance, so a client enables caching only + /// for a region in which it does not perform such mutations (e.g. a pass + /// that only moves operations). fir::AliasAnalysis::Source getSource(mlir::Value, bool getLastInstantiationPoint = false, bool collectScopedOrigins = true); + /// Enable memoization of getSource() results on this analysis instance. + /// Caching is opt-in and off by default; a client that does not mutate the + /// IR in a way that affects getSource() (see getSource()) may enable it to + /// avoid recomputing sources for repeated queries. + void enableSourceCache(); + + /// Disable getSource() memoization and drop any cached entries. + void disableSourceCache(); + + /// Testing only: number of entries currently held in the getSource() cache. + std::size_t getSourceCacheSizeForTesting() const { + return getSourceCache.size(); + } + + /// Testing only: cumulative getSource() cache hits / misses on this instance. + std::size_t getSourceCacheHitsForTesting() const { return sourceCacheHits; } + std::size_t getSourceCacheMissesForTesting() const { + return sourceCacheMisses; + } + /// Return true, if `ty` is a reference type to a boxed /// POINTER object or a raw fir::PointerType. static bool isPointerReference(mlir::Type ty); @@ -370,6 +401,16 @@ struct AliasAnalysis { bool functionHasMultipleScopes(mlir::Value v); private: + /// Compute the memory source of a value. This is the uncached + /// implementation of getSource(); getSource() is a thin wrapper that + /// memoizes the result when source caching is enabled. + fir::AliasAnalysis::Source getSourceImpl(mlir::Value v, + bool getLastInstantiationPoint, + bool collectScopedOrigins); + + /// Clear the getSource() memoization cache. + void clearSourceCache() { getSourceCache.clear(); } + /// Build an intermediate Source rooted at the declare captured by the /// snapshot. Reuses getSource(declValue) for the SourceKind / origin /// classification (with collectScopedOrigins=false), then overrides @@ -446,6 +487,21 @@ struct AliasAnalysis { /// functionHasMultipleScopes(); both true and false are cached so that /// repeated queries are O(1) without re-walking the function body. llvm::DenseMap multiScopeCache; + + /// Opt-in memoization of getSource() results, keyed on the queried value + /// and the two boolean flags (getLastInstantiationPoint, + /// collectScopedOrigins) packed into the unsigned. Only consulted/populated + /// while \c sourceCacheEnabled is set. This is a frozen snapshot cache with + /// no automatic invalidation (see getSource()). + llvm::DenseMap, Source> getSourceCache; + + /// Whether getSource() should consult/populate getSourceCache. + bool sourceCacheEnabled = false; + + /// Testing-only counters (see getSourceCacheHitsForTesting()). Incremented + /// on each getSource() cache hit / miss. + std::size_t sourceCacheHits = 0; + std::size_t sourceCacheMisses = 0; }; inline bool operator==(const AliasAnalysis::Source::SourceOrigin &lhs, diff --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.td b/flang/include/flang/Optimizer/Dialect/FIRAttr.td index 3bb1f443f3a5d..c53a2b869e968 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRAttr.td +++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.td @@ -78,14 +78,19 @@ def FIRfuncPure : I32BitEnumAttrCaseBit<"pure", 1>; def FIRfuncNonRecursive : I32BitEnumAttrCaseBit<"non_recursive", 2>; def FIRfuncSimple : I32BitEnumAttrCaseBit<"simple", 3>; def FIRfuncBind_c : I32BitEnumAttrCaseBit<"bind_c", 4>; -def FIRfuncRecursive : I32BitEnumAttrCaseBit<"recursive", 5>; +def FIRfuncRecursive : I32BitEnumAttrCaseBit<"recursive", 5>; +/// We also track whether a procedure call is to an "intrinsic", meaning that the +/// callee was found in an instrinsic module. This allows us to make sure calls are +/// to known intrinsic functions and not user-defined functions with the same +/// name when optimizing. +def FIRfuncIntrinsic : I32BitEnumAttrCaseBit<"intrinsic", 6>; def fir_FortranProcedureFlagsEnum : I32BitEnumAttr<"FortranProcedureFlagsEnum", "Fortran procedure attributes", [FIRfuncNoAttributes, FIRfuncElemental, FIRfuncPure, FIRfuncNonRecursive, FIRfuncSimple, FIRfuncBind_c, - FIRfuncRecursive]> { + FIRfuncRecursive, FIRfuncIntrinsic]> { let separator = ", "; let cppNamespace = "::fir"; let genSpecializedAttr = 0; diff --git a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h index a39d517412c07..31e1593e11325 100644 --- a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h +++ b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h @@ -99,6 +99,20 @@ struct OutlineRematerializationModel bool isRematerializationCandidate(mlir::Operation *op) const; }; +/// External model for OutlineIdentityOperandOpInterface. +/// Drops the dummy_scope operand (an identity token that must not be +/// duplicated) from a [hl]fir.declare instance that has been sunk or +/// rematerialized into an offload region. Alias analysis falls back to a +/// dominance-based lookup of the enclosing dummy scope when this operand is +/// absent, so correctness is preserved without needing to keep or clone the +/// original operand. +template +struct OutlineIdentityOperandDeclareModel + : public mlir::acc::OutlineIdentityOperandOpInterface::ExternalModel< + OutlineIdentityOperandDeclareModel, Op> { + void dropOutlinedIdentityOperands(mlir::Operation *op) const; +}; + /// External model for OffloadRegionOpInterface. /// This interface marks operations whose regions are targets for offloading /// and outlining. diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index 6ca309a05d438..c84c0b27505bb 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -9,6 +9,7 @@ #include "flang/Lower/CallInterface.h" #include "flang/Evaluate/fold.h" #include "flang/Lower/Bridge.h" +#include "flang/Lower/ConvertCall.h" #include "flang/Lower/Mangler.h" #include "flang/Lower/OpenACC.h" #include "flang/Lower/PFTBuilder.h" @@ -1592,6 +1593,9 @@ Fortran::lower::CallInterface::getProcedureAttrs( flags = flags | fir::FortranProcedureFlagsEnum::recursive; } } + if constexpr (std::is_same_v) + if (Fortran::lower::isIntrinsicModuleProcRef(side().getCallDescription())) + flags = flags | fir::FortranProcedureFlagsEnum::intrinsic; if (flags != fir::FortranProcedureFlagsEnum::none) return fir::FortranProcedureFlagsEnumAttr::get(mlirContext, flags); return nullptr; diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp index 435f7aa6b5bf1..0c518fc460375 100644 --- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp +++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include +#include using namespace mlir; @@ -1107,9 +1108,40 @@ static mlir::Value walkBlockArgPassThroughs(mlir::Value v) { return v; } +void AliasAnalysis::enableSourceCache() { sourceCacheEnabled = true; } + +void AliasAnalysis::disableSourceCache() { + sourceCacheEnabled = false; + clearSourceCache(); +} + AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v, bool getLastInstantiationPoint, bool collectScopedOrigins) { + if (!sourceCacheEnabled) + return getSourceImpl(v, getLastInstantiationPoint, collectScopedOrigins); + + // Key on the queried value and the two boolean flags. Recursive sub-queries + // go through this same wrapper, so the whole walk is memoized. + std::pair key{v, + (getLastInstantiationPoint ? 1u : 0u) | + (collectScopedOrigins ? 2u : 0u)}; + auto it = getSourceCache.find(key); + if (it != getSourceCache.end()) { + ++sourceCacheHits; + return it->second; + } + + ++sourceCacheMisses; + Source source = + getSourceImpl(v, getLastInstantiationPoint, collectScopedOrigins); + getSourceCache.try_emplace(key, source); + return source; +} + +AliasAnalysis::Source +AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint, + bool collectScopedOrigins) { // If v is a pass-through block argument (see walkBlockArgPassThroughs), // continue from the underlying operand so the tracking loop below has a // defining op to chew on. Without this, a recursive query like the one in diff --git a/flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp b/flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp index 61c5e8131216e..ca200ac2cd02a 100644 --- a/flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp @@ -882,9 +882,13 @@ CUDAIntrinsicLibrary::genAtomicCas(mlir::Type resultType, .getResult(0); auto cmpxchg = mlir::LLVM::AtomicCmpXchgOp::create( builder, loc, address, arg1, arg2, successOrdering, failureOrdering); - mlir::Value boolResult = - mlir::LLVM::ExtractValueOp::create(builder, loc, cmpxchg, 1); - return builder.createConvert(loc, resultType, boolResult); + // atomicCAS returns the value originally stored at the address, which is the + // first element of the cmpxchg result, not the success flag. + mlir::Value oldValue = + mlir::LLVM::ExtractValueOp::create(builder, loc, cmpxchg, 0); + if (mlir::isa(resultType)) + return mlir::LLVM::BitcastOp::create(builder, loc, resultType, oldValue); + return builder.createConvert(loc, resultType, oldValue); } mlir::Value diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp index 590619a31a33f..8e4b55fe5f4a8 100644 --- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp +++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp @@ -143,6 +143,26 @@ bool OutlineRematerializationModel< fir::ConvertOp::isIntegerCompatible(outTy); } +template <> +void OutlineIdentityOperandDeclareModel< + fir::DeclareOp>::dropOutlinedIdentityOperands(mlir::Operation *op) const { + auto declareOp = mlir::cast(op); + if (declareOp.getDummyScope()) { + declareOp.getDummyScopeMutable().clear(); + declareOp->removeAttr(declareOp.getDummyArgNoAttrName()); + } +} + +template <> +void OutlineIdentityOperandDeclareModel< + hlfir::DeclareOp>::dropOutlinedIdentityOperands(mlir::Operation *op) const { + auto declareOp = mlir::cast(op); + if (declareOp.getDummyScope()) { + declareOp.getDummyScopeMutable().clear(); + declareOp->removeAttr(declareOp.getDummyArgNoAttrName()); + } +} + // Helper to recursively process address-of operations in derived type // descriptors and collect all needed fir.globals. static void processAddrOfOpInDerivedTypeDescriptor( diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp index e18fc5f2782ad..e0f0450ec119c 100644 --- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp +++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp @@ -39,7 +39,7 @@ static llvm::cl::opt useAccReductionCombine( "openacc-use-reduction-combine", llvm::cl::desc("Whether to generate acc.reduction_combine. Does not " "control reduction for MIN/MAX and logical reductions."), - llvm::cl::init(false)); + llvm::cl::init(true)); static llvm::cl::opt useAccReductionCombineAll( "openacc-use-reduction-combine-all", diff --git a/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp b/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp index 070208d22ba05..7e5eeda1f5de9 100644 --- a/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp +++ b/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp @@ -53,6 +53,8 @@ void registerOpenACCExtensions(mlir::DialectRegistry ®istry) { PartialEntityAccessModel>(*ctx); fir::DeclareOp::attachInterface>( *ctx); + fir::DeclareOp::attachInterface< + OutlineIdentityOperandDeclareModel>(*ctx); fir::AddrOfOp::attachInterface(*ctx); fir::GlobalOp::attachInterface(*ctx); @@ -94,6 +96,8 @@ void registerOpenACCExtensions(mlir::DialectRegistry ®istry) { PartialEntityAccessModel>(*ctx); hlfir::DeclareOp::attachInterface< PartialEntityAccessModel>(*ctx); + hlfir::DeclareOp::attachInterface< + OutlineIdentityOperandDeclareModel>(*ctx); }); // Register CUF operation interfaces diff --git a/flang/lib/Optimizer/Transforms/LoopInvariantCodeMotion.cpp b/flang/lib/Optimizer/Transforms/LoopInvariantCodeMotion.cpp index 9a4b88f8f82b3..26388c6758daa 100644 --- a/flang/lib/Optimizer/Transforms/LoopInvariantCodeMotion.cpp +++ b/flang/lib/Optimizer/Transforms/LoopInvariantCodeMotion.cpp @@ -24,6 +24,7 @@ #include "mlir/Transforms/LoopInvariantCodeMotionUtils.h" #include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/DebugLog.h" +#include namespace fir { #define GEN_PASS_DEF_LOOPINVARIANTCODEMOTION @@ -265,7 +266,15 @@ void LoopInvariantCodeMotion::runOnOperation() { LDBG() << "Enter [HL]FIR LoopInvariantCodeMotion()"; auto &aliasAnalysis = getAnalysis(); - aliasAnalysis.addAnalysisImplementation(fir::AliasAnalysis{}); + // Enable getSource() memoization on the FIR AliasAnalysis for the duration + // of this pass. This is a frozen-snapshot cache with no automatic + // invalidation, but it is sound here because LICM only moves operations, so + // getSource()'s inputs are unchanged across the hoists. The cache lives no + // longer than this analysis instance, which the pass manager drops when the + // analysis is invalidated after the pass. + fir::AliasAnalysis firAliasAnalysis; + firAliasAnalysis.enableSourceCache(); + aliasAnalysis.addAnalysisImplementation(std::move(firAliasAnalysis)); std::function shouldMoveOutOfLoop = [&](Operation *op, LoopLikeOpInterface loopLike, diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 02928401a382a..bb8145384d9ee 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1673,6 +1673,13 @@ void OmpStructureChecker::ChecksOnOrderedAsBlock() { context_.Say(GetContext().directiveSource, "An ORDERED directive with SIMD clause must be closely nested in a " "SIMD or worksharing-loop SIMD region"_err_en_US); + } else if (CurrentDirectiveIsNested() && + FindClause(llvm::omp::Clause::OMPC_simd) && + FindClause(llvm::omp::Clause::OMPC_threads) && isNestedInSIMD && + !isNestedInDoSIMD) { + context_.Say(GetContext().directiveSource, + "An ORDERED directive with SIMD and THREADS clauses must be closely " + "nested in a worksharing-loop SIMD region"_err_en_US); } if (isNestedInDo && (noOrderedClause || isOrderedClauseWithPara)) { context_.Say(GetContext().directiveSource, diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 6079cfced9151..5a92cfd738ef4 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -833,6 +833,10 @@ class ModuleVisitor : public virtual ScopeHandler { nonIntrinsicUses_.clear(); } +protected: + std::optional implicitUseModuleBeingResolved_; + std::set implicitUseModulesInCurrentProgram_; + private: // The location of the last AccessStmt without access-ids, if any. std::optional prevAccessStmt_; @@ -3916,16 +3920,44 @@ void ModuleVisitor::AddUseForCommonBlocks() { } void ModuleVisitor::AddImplicitUseModules() { + if (InModuleFile() || currScope().kind() != Scope::Kind::Subprogram) { + return; + } for (const std::string &module : context().implicitUseModules()) { if (module.empty()) { continue; } SourceName moduleName{module}; - std::optional currModuleName{currScope().GetName()}; - if (currScope().IsModule() && currModuleName && - *currModuleName == moduleName) { + if (implicitUseModulesInCurrentProgram_.count(module) != 0) { + continue; + } + if (implicitUseModuleBeingResolved_ && + *implicitUseModuleBeingResolved_ == module) { + continue; + } + bool isContainedInImplicitModule{false}; + for (const Scope *scope{&currScope()}; !scope->IsTopLevel(); + scope = &scope->parent()) { + if (scope->kind() == Scope::Kind::Module) { + if (std::optional scopeName{scope->GetName()}; + scopeName && scopeName->ToString() == module) { + // Do not implicitly USE a module while resolving anything contained + // in that module; doing so would be a self USE. + isContainedInImplicitModule = true; + break; + } + } + } + if (isContainedInImplicitModule) { continue; } + if (auto it{context().globalScope().find(moduleName)}; + it != context().globalScope().end()) { + if (Scope *scope{it->second->scope()}; + scope && DoesScopeContain(scope, currScope())) { + continue; + } + } parser::Name name{moduleName}; std::optional isIntrinsic; if (currScope().IsModule() && currScope().symbol() && @@ -11007,6 +11039,10 @@ bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) { return false; } ProgramTree &root{ProgramTree::Build(x, context())}; + auto implicitUseModuleBeingResolvedRestorer{ + common::ScopedSet(implicitUseModuleBeingResolved_, + root.IsModule() ? std::optional{root.name().ToString()} + : implicitUseModuleBeingResolved_)}; SetScope(topScope_); ResolveSpecificationParts(root); FinishSpecificationParts(root); @@ -11048,6 +11084,7 @@ bool ResolveNamesVisitor::Pre(const parser::Program &x) { ImplicitRulesVisitor::BeginScope(*hermetic); } std::map modules; + std::set moduleNamesInCurrentProgram; std::set uses; bool disordered{false}; for (const auto &progUnit : x.v) { @@ -11057,6 +11094,7 @@ bool ResolveNamesVisitor::Pre(const parser::Program &x) { const auto &moduleStmt{ std::get>(mod.t)}; const SourceName &name{moduleStmt.statement.v.source}; + moduleNamesInCurrentProgram.insert(name.ToString()); if (auto iter{modules.find(name)}; iter != modules.end()) { Say(name, "Module '%s' appears multiple times in a compilation unit"_err_en_US) @@ -11080,6 +11118,7 @@ bool ResolveNamesVisitor::Pre(const parser::Program &x) { uses.insert(used); } } + implicitUseModulesInCurrentProgram_ = std::move(moduleNamesInCurrentProgram); if (!disordered) { return true; } @@ -11174,6 +11213,10 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) { if (node.isSpecificationPartResolved()) { return; // been here already } + auto implicitUseModuleBeingResolvedRestorer{ + common::ScopedSet(implicitUseModuleBeingResolved_, + node.IsModule() ? std::optional{node.name().ToString()} + : implicitUseModuleBeingResolved_)}; node.set_isSpecificationPartResolved(); if (!BeginScopeForNode(node)) { return; // an error prevented scope from being created diff --git a/flang/test/Driver/bbc-implicit-use-module.f90 b/flang/test/Driver/bbc-implicit-use-module.f90 index 733ad69580c1c..c7c1af9b64231 100644 --- a/flang/test/Driver/bbc-implicit-use-module.f90 +++ b/flang/test/Driver/bbc-implicit-use-module.f90 @@ -1,7 +1,10 @@ ! Test bbc's test-only implicit USE module hook. ! RUN: split-file %s %t +! RUN: mkdir -p %t/self +! RUN: bbc -module %t/self -implicit-use-module implicit_mod %t/implicit_mod.f90 -o /dev/null ! RUN: bbc -module %t %t/implicit_mod.f90 -o /dev/null +! RUN: not bbc -emit-hlfir -I %t -implicit-use-module implicit_mod %t/use_in_module.f90 -o - 2>&1 | FileCheck %s --check-prefix=MODULE-SCOPE ! RUN: bbc -emit-hlfir -fopenacc -I %t -implicit-use-module implicit_mod %t/use_implicit.f90 -o - | FileCheck %s !--- implicit_mod.f90 @@ -10,17 +13,30 @@ module implicit_mod integer :: common_value integer :: module_value = 42 common /implicit_common/ common_value +contains + subroutine contained + integer :: x + x = module_value + end subroutine end module !--- use_implicit.f90 subroutine use_implicit - integer :: x + real :: x !$acc data copy(/implicit_common/) x = module_value + common_value !$acc end data end subroutine +!--- use_in_module.f90 +module use_in_module + implicit none + integer :: x = module_value +end module + +! MODULE-SCOPE: No explicit type declared for 'module_value' + ! CHECK-LABEL: func.func @_QPuse_implicit() ! CHECK-DAG: fir.address_of(@_QMimplicit_modEmodule_value) : !fir.ref ! CHECK-DAG: %[[COMMON:.*]] = fir.address_of(@implicit_common_) : !fir.ref> -! CHECK-DAG: acc.copyin varPtr(%[[COMMON]] +! CHECK-DAG: acc.copyin varPtr(%[[COMMON]] : !fir.ref>) -> !fir.ref> {dataClause = #acc, name = "implicit_common"} diff --git a/flang/test/Fir/OpenACC/offload-livein-value-canonicalization.fir b/flang/test/Fir/OpenACC/offload-livein-value-canonicalization.fir index e692e5fb6dc4f..8b1d4cd0b1e16 100644 --- a/flang/test/Fir/OpenACC/offload-livein-value-canonicalization.fir +++ b/flang/test/Fir/OpenACC/offload-livein-value-canonicalization.fir @@ -467,3 +467,75 @@ func.func @test_undef_slice_rematerialize(%arg0: !fir.box>) // CHECK: %[[UNDEF_INNER:.*]] = fir.undefined index // CHECK: %[[SLICE_INNER:.*]] = fir.slice {{.*}}, %[[UNDEF_INNER]], %[[UNDEF_INNER]] // CHECK: fir.rebox %arg0 [%[[SLICE_INNER]]] + +// ----- + +// Test that fir.declare's dummy_scope operand is dropped, not duplicated, +// when the declare is sunk into an offload region. Regression test: after +// inlining, a fir.declare for a dummy argument aliasing a device-valid +// global (e.g. one with !$ACC DECLARE COPYIN) is sunk/rematerialized into +// the offload region. Its dummy_scope operand is an identity token (see +// fir.dummy_scope) that must never be duplicated, so it must be dropped +// from the sunk/cloned declare instead of being left as an illegal live-in +// or cloned alongside it. + +fir.global @global_for_dummy_scope {acc.declare = #acc.declare} : i32 { + %0 = arith.constant 0 : i32 + fir.has_value %0 : i32 +} + +func.func private @use_ref(!fir.ref) -> () + +func.func @test_dummy_scope_sink() { + %addr = fir.address_of(@global_for_dummy_scope) : !fir.ref + %scope = fir.dummy_scope : !fir.dscope + %decl = fir.declare %addr dummy_scope %scope {uniq_name = "global"} : (!fir.ref, !fir.dscope) -> !fir.ref + acc.serial { + fir.call @use_ref(%decl) : (!fir.ref) -> () + acc.yield + } + return +} + +// CHECK-LABEL: @test_dummy_scope_sink +// The dummy scope stays outside, untouched and unduplicated: nothing +// references it anymore once the declare's operand is dropped. +// CHECK: fir.dummy_scope +// CHECK: acc.serial { +// CHECK-DAG: fir.address_of(@global_for_dummy_scope) +// CHECK-DAG: %[[DECL:.*]] = fir.declare %{{.*}} {uniq_name = "global"} : (!fir.ref) -> !fir.ref +// CHECK: fir.call @use_ref(%[[DECL]]) + +// ----- + +// Test fir.declare rematerialization (used both inside and outside region): +// the outer declare keeps its dummy_scope untouched, while the clone made +// for the region drops it rather than duplicating the scope. + +fir.global @global_for_dummy_scope_remat {acc.declare = #acc.declare} : i32 { + %0 = arith.constant 0 : i32 + fir.has_value %0 : i32 +} + +func.func private @use_ref(!fir.ref) -> () + +func.func @test_dummy_scope_rematerialize() { + %addr = fir.address_of(@global_for_dummy_scope_remat) : !fir.ref + %scope = fir.dummy_scope : !fir.dscope + %decl = fir.declare %addr dummy_scope %scope {uniq_name = "global"} : (!fir.ref, !fir.dscope) -> !fir.ref + fir.call @use_ref(%decl) : (!fir.ref) -> () + acc.serial { + fir.call @use_ref(%decl) : (!fir.ref) -> () + acc.yield + } + return +} + +// CHECK-LABEL: @test_dummy_scope_rematerialize +// CHECK: %[[SCOPE:.*]] = fir.dummy_scope +// CHECK: %[[DECL_OUTER:.*]] = fir.declare %{{.*}} dummy_scope %[[SCOPE]] {uniq_name = "global"} +// CHECK: fir.call @use_ref(%[[DECL_OUTER]]) +// CHECK: acc.serial { +// CHECK-DAG: fir.address_of(@global_for_dummy_scope_remat) +// CHECK-DAG: %[[DECL_INNER:.*]] = fir.declare %{{.*}} {uniq_name = "global"} : (!fir.ref) -> !fir.ref +// CHECK: fir.call @use_ref(%[[DECL_INNER]]) diff --git a/flang/test/Lower/CUDA/cuda-device-proc.cuf b/flang/test/Lower/CUDA/cuda-device-proc.cuf index 81286dec57590..864d1b7169bb1 100644 --- a/flang/test/Lower/CUDA/cuda-device-proc.cuf +++ b/flang/test/Lower/CUDA/cuda-device-proc.cuf @@ -151,44 +151,44 @@ end ! CHECK: %{{.*}} = nvvm.read.ptx.sreg.clock64 : i64 ! CHECK: %{{.*}} = nvvm.read.ptx.sreg.globaltimer : i64 -! CHECK: %{{.*}} = fir.call @__nv_popc(%{{.*}}) proc_attrs fastmath : (i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_popcll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_ffs(%{{.*}}) proc_attrs fastmath : (i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_ffsll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_brev(%{{.*}}) proc_attrs fastmath : (i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_brevll(%{{.*}}) proc_attrs fastmath : (i64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_clz(%{{.*}}) proc_attrs fastmath : (i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_clzll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_fast_cosf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 -! CHECK: %{{.*}} = fir.call @__ddiv_rn(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 -! CHECK: %{{.*}} = fir.call @__ddiv_rz(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 -! CHECK: %{{.*}} = fir.call @__ddiv_ru(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 -! CHECK: %{{.*}} = fir.call @__ddiv_rd(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_double2float_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_double2float_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_double2float_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_double2float_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_double2int_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2int_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2int_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2int_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2uint_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2uint_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2uint_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2uint_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_mul24(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_umul24(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_fast_powf(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f32, f32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ull2double_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ull2double_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ull2double_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ull2double_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_float2half_rn(%{{.*}}) proc_attrs fastmath : (f32) -> f16 -! CHECK: %{{.*}} = fir.call @__nv_half2float(%{{.*}}) proc_attrs fastmath : (f16) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ll2double_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ll2double_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ll2double_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ll2double_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_popc(%{{.*}}) proc_attrs fastmath : (i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_popcll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_ffs(%{{.*}}) proc_attrs fastmath : (i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_ffsll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_brev(%{{.*}}) proc_attrs fastmath : (i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_brevll(%{{.*}}) proc_attrs fastmath : (i64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_clz(%{{.*}}) proc_attrs fastmath : (i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_clzll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_fast_cosf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__ddiv_rn(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 +! CHECK: %{{.*}} = fir.call @__ddiv_rz(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 +! CHECK: %{{.*}} = fir.call @__ddiv_ru(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 +! CHECK: %{{.*}} = fir.call @__ddiv_rd(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_double2float_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_double2float_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_double2float_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_double2float_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_double2int_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2int_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2int_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2int_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2uint_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2uint_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2uint_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2uint_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_mul24(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_umul24(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_fast_powf(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f32, f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2double_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ull2double_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ull2double_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ull2double_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_float2half_rn(%{{.*}}) proc_attrs fastmath : (f32) -> f16 +! CHECK: %{{.*}} = fir.call @__nv_half2float(%{{.*}}) proc_attrs fastmath : (f16) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2double_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ll2double_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ll2double_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ll2double_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f64 subroutine host1() integer, device :: a(32) @@ -311,7 +311,8 @@ end subroutine ! CHECK: %[[BCAST2:.*]] = llvm.bitcast %{{.*}} : f64 to i64 ! CHECK: %[[CAST:.*]] = builtin.unrealized_conversion_cast %{{.*}}#0 : !fir.ref to !llvm.ptr ! CHECK: %[[ATOMIC:.*]] = llvm.cmpxchg %[[CAST]], %[[BCAST1]], %[[BCAST2]] acq_rel monotonic : !llvm.ptr, i64 -! CHECK: %[[RES:.*]] = llvm.extractvalue %[[ATOMIC]][1] : !llvm.struct<(i64, i1)> +! CHECK: %[[RES:.*]] = llvm.extractvalue %[[ATOMIC]][0] : !llvm.struct<(i64, i1)> +! CHECK: %{{.*}} = llvm.bitcast %[[RES]] : i64 to f64 attributes(global) subroutine __ldXXi4(b) integer, device :: b(*) @@ -499,10 +500,9 @@ end subroutine ! CHECK-LABEL: func.func @_QPtestatomiccasloop ! CHECK: %[[CMP_XCHG:.*]] = llvm.cmpxchg %15, %c0_i32, %c1_i32 acq_rel monotonic : !llvm.ptr, i32 -! CHECK: %[[CMP_XCHG_EV:.*]] = llvm.extractvalue %[[CMP_XCHG]][1] : !llvm.struct<(i32, i1)> -! CHECK: %[[CASTED_CMP_XCHG_EV:.*]] = fir.convert %[[CMP_XCHG_EV]] : (i1) -> i32 +! CHECK: %[[CMP_XCHG_EV:.*]] = llvm.extractvalue %[[CMP_XCHG]][0] : !llvm.struct<(i32, i1)> ! CHECK: %{{.*}} = arith.constant 1 : i32 -! CHECK: %19 = arith.cmpi eq, %[[CASTED_CMP_XCHG_EV]], %{{.*}} : i32 +! CHECK: %{{.*}} = arith.cmpi eq, %[[CMP_XCHG_EV]], %{{.*}} : i32 attributes(global) subroutine test_barrier_try_wait() integer :: istat diff --git a/flang/test/Lower/CUDA/cuda-libdevice.cuf b/flang/test/Lower/CUDA/cuda-libdevice.cuf index 7c6eda21a6e75..7718a84c08309 100644 --- a/flang/test/Lower/CUDA/cuda-libdevice.cuf +++ b/flang/test/Lower/CUDA/cuda-libdevice.cuf @@ -9,7 +9,7 @@ attributes(global) subroutine test_sad() end subroutine ! CHECK-LABEL: _QPtest_sad -! CHECK: %{{.*}} = fir.call @__nv_sad(%{{.*}}, %{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32, i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_sad(%{{.*}}, %{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32, i32) -> i32 attributes(global) subroutine test_usad() integer :: res @@ -18,7 +18,7 @@ attributes(global) subroutine test_usad() end subroutine ! CHECK-LABEL: _QPtest_usad -! CHECK: %{{.*}} = fir.call @__nv_usad(%{{.*}}, %{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32, i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_usad(%{{.*}}, %{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32, i32) -> i32 attributes(global) subroutine test_dsqrt_rX() double precision :: res @@ -30,10 +30,10 @@ attributes(global) subroutine test_dsqrt_rX() end subroutine ! CHECK-LABEL: _QPtest_dsqrt_rx -! CHECK: %{{.*}} = fir.call @__dsqrt_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__dsqrt_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__dsqrt_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__dsqrt_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__dsqrt_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__dsqrt_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__dsqrt_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__dsqrt_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f64 attributes(global) subroutine test_uint2float_rX() real :: res @@ -45,10 +45,10 @@ attributes(global) subroutine test_uint2float_rX() end subroutine ! CHECK-LABEL: _QPtest_uint2float_rx -! CHECK: %{{.*}} = fir.call @__nv_uint2float_rd(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_uint2float_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_uint2float_ru(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_uint2float_rz(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_uint2float_rd(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_uint2float_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_uint2float_ru(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_uint2float_rz(%{{.*}}) proc_attrs fastmath : (i32) -> f32 attributes(global) subroutine test_uint2double_rn() double precision :: res @@ -57,7 +57,7 @@ attributes(global) subroutine test_uint2double_rn() end subroutine ! CHECK-LABEL: _QPtest_uint2double_rn -! CHECK: %{{.*}} = fir.call @__nv_uint2double_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_uint2double_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f64 attributes(global) subroutine test_ull2dloat_rX() real :: res @@ -69,10 +69,10 @@ attributes(global) subroutine test_ull2dloat_rX() end subroutine ! CHECK-LABEL: _QPtest_ull2dloat_rx -! CHECK: %{{.*}} = fir.call @__nv_ull2float_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ull2float_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ull2float_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ull2float_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2float_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2float_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2float_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2float_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f32 attributes(global) subroutine test_log() real :: res @@ -83,9 +83,9 @@ attributes(global) subroutine test_log() end subroutine ! CHECK-LABEL: _QPtest_log -! CHECK: %{{.*}} = fir.call @__nv_fast_logf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_fast_log2f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_fast_log10f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_logf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_log2f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_log10f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_sincosf() real :: r, s, c @@ -93,7 +93,7 @@ attributes(global) subroutine test_sincosf() end subroutine ! CHECK-LABEL: _QPtest_sincosf -! CHECK: fir.call @__nv_fast_sincosf(%{{.*}}, %{{.*}}#0, %{{.*}}#0) proc_attrs fastmath : (f32, !fir.ref, !fir.ref) -> () +! CHECK: fir.call @__nv_fast_sincosf(%{{.*}}, %{{.*}}#0, %{{.*}}#0) proc_attrs fastmath : (f32, !fir.ref, !fir.ref) -> () attributes(global) subroutine test_sinf() real :: res @@ -102,7 +102,7 @@ attributes(global) subroutine test_sinf() end subroutine ! CHECK-LABEL: _QPtest_sinf -! CHECK: %{{.*}} = fir.call @__nv_fast_sinf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_sinf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_tanf() real :: res @@ -111,7 +111,7 @@ attributes(global) subroutine test_tanf() end subroutine ! CHECK-LABEL: _QPtest_tanf -! CHECK: %{{.*}} = fir.call @__nv_fast_tanf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_tanf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_exp() real :: res @@ -121,8 +121,8 @@ attributes(global) subroutine test_exp() end subroutine ! CHECK-LABEL: _QPtest_exp -! CHECK: %{{.*}} = fir.call @__nv_fast_expf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_fast_exp10f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_expf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_exp10f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_double2ll_rX() integer(8) :: res @@ -134,10 +134,10 @@ attributes(global) subroutine test_double2ll_rX() end subroutine ! CHECK-LABEL: _QPtest_double2ll_rx -! CHECK: %{{.*}} = fir.call @__nv_double2ll_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ll_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ll_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ll_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ll_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ll_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ll_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ll_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i64 attributes(global) subroutine test_drcp_rX() double precision :: res @@ -149,10 +149,10 @@ attributes(global) subroutine test_drcp_rX() end subroutine ! CHECK-LABEL: _QPtest_drcp_rx -! CHECK: %{{.*}} = fir.call @__drcp_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__drcp_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__drcp_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__drcp_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__drcp_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__drcp_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__drcp_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__drcp_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f64 attributes(global) subroutine test_double2ull_rX() integer(8) :: res @@ -164,10 +164,10 @@ attributes(global) subroutine test_double2ull_rX() end subroutine ! CHECK-LABEL: _QPtest_double2ull_rx -! CHECK: %{{.*}} = fir.call @__nv_double2ull_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ull_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ull_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ull_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ull_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ull_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ull_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ull_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i64 attributes(global) subroutine test_saturatef() real :: res @@ -176,7 +176,7 @@ attributes(global) subroutine test_saturatef() end subroutine ! CHECK-LABEL: _QPtest_saturatef -! CHECK: %{{.*}} = fir.call @__nv_saturatef(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_saturatef(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_float2ll_rX() integer(8) :: res @@ -188,10 +188,10 @@ attributes(global) subroutine test_float2ll_rX() end subroutine ! CHECK-LABEL: _QPtest_float2ll_rx -! CHECK: %{{.*}} = fir.call @__nv_float2ll_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_float2ll_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_float2ll_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_float2ll_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_float2ll_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_float2ll_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_float2ll_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_float2ll_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i64 attributes(global) subroutine test_ll2float_rX() real :: res @@ -203,10 +203,10 @@ attributes(global) subroutine test_ll2float_rX() end subroutine ! CHECK-LABEL: _QPtest_ll2float_rx -! CHECK: %{{.*}} = fir.call @__nv_ll2float_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ll2float_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ll2float_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ll2float_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2float_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2float_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2float_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2float_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f32 attributes(global) subroutine test_int2float_rX() real :: res @@ -218,10 +218,10 @@ attributes(global) subroutine test_int2float_rX() end subroutine ! CHECK-LABEL: _QPtest_int2float_rx -! CHECK: %{{.*}} = fir.call @__nv_int2float_rd(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_int2float_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_int2float_ru(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_int2float_rz(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int2float_rd(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int2float_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int2float_ru(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int2float_rz(%{{.*}}) proc_attrs fastmath : (i32) -> f32 attributes(global) subroutine test_float2int_rX() integer :: res @@ -233,10 +233,10 @@ attributes(global) subroutine test_float2int_rX() end subroutine ! CHECK-LABEL: _QPtest_float2int_rx -! CHECK: %{{.*}} = fir.call @__nv_float2int_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2int_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2int_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2int_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2int_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2int_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2int_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2int_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i32 attributes(global) subroutine test_float2uint_rX() integer :: res @@ -248,10 +248,10 @@ attributes(global) subroutine test_float2uint_rX() end subroutine ! CHECK-LABEL: _QPtest_float2uint_rx -! CHECK: %{{.*}} = fir.call @__nv_float2uint_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2uint_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2uint_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2uint_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2uint_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2uint_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2uint_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2uint_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i32 attributes(global) subroutine test_int2double_rn() double precision :: res @@ -260,7 +260,7 @@ attributes(global) subroutine test_int2double_rn() end subroutine ! CHECK-LABEL: _QPtest_int2double_rn -! CHECK: %{{.*}} = fir.call @__nv_int2double_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_int2double_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f64 attributes(global) subroutine test_fdividef() real :: res @@ -269,7 +269,7 @@ attributes(global) subroutine test_fdividef() end subroutine ! CHECK-LABEL: _QPtest_fdividef -! CHECK: %{{.*}} = fir.call @__nv_fast_fdividef(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f32, f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_fdividef(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f32, f32) -> f32 attributes(global) subroutine test_double_as_longlong() integer(8) :: res @@ -278,7 +278,7 @@ attributes(global) subroutine test_double_as_longlong() end subroutine ! CHECK-LABEL: _QPtest_double_as_longlong -! CHECK: %{{.*}} = fir.call @__nv_double_as_longlong(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double_as_longlong(%{{.*}}) proc_attrs fastmath : (f64) -> i64 attributes(global) subroutine test_longlong_as_double() integer(8) :: i @@ -287,7 +287,7 @@ attributes(global) subroutine test_longlong_as_double() end subroutine ! CHECK-LABEL: _QPtest_longlong_as_double -! CHECK: %{{.*}} = fir.call @__nv_longlong_as_double(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_longlong_as_double(%{{.*}}) proc_attrs fastmath : (i64) -> f64 attributes(global) subroutine test_int_as_float() integer :: i @@ -296,7 +296,7 @@ attributes(global) subroutine test_int_as_float() end subroutine ! CHECK-LABEL: _QPtest_int_as_float -! CHECK: %{{.*}} = fir.call @__nv_int_as_float(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int_as_float(%{{.*}}) proc_attrs fastmath : (i32) -> f32 attributes(global) subroutine test_float_as_int() integer :: res @@ -305,7 +305,7 @@ attributes(global) subroutine test_float_as_int() end subroutine ! CHECK-LABEL: _QPtest_float_as_int -! CHECK: %{{.*}} = fir.call @__nv_float_as_int(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float_as_int(%{{.*}}) proc_attrs fastmath : (f32) -> i32 attributes(global) subroutine test_double2loint() integer :: res @@ -314,7 +314,7 @@ attributes(global) subroutine test_double2loint() end subroutine ! CHECK-LABEL: _QPtest_double2loint -! CHECK: %{{.*}} = fir.call @__nv_double2loint(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2loint(%{{.*}}) proc_attrs fastmath : (f64) -> i32 attributes(global) subroutine test_double2hiint() integer :: res @@ -323,7 +323,7 @@ attributes(global) subroutine test_double2hiint() end subroutine ! CHECK-LABEL: _QPtest_double2hiint -! CHECK: %{{.*}} = fir.call @__nv_double2hiint(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2hiint(%{{.*}}) proc_attrs fastmath : (f64) -> i32 attributes(global) subroutine test_hiloint2double() double precision :: res @@ -332,4 +332,4 @@ attributes(global) subroutine test_hiloint2double() end subroutine ! CHECK-LABEL: _QPtest_hiloint2double -! CHECK: %{{.*}} = fir.call @__nv_hiloint2double(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_hiloint2double(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> f64 diff --git a/flang/test/Lower/OpenACC/acc-reduction-maxmin.f90 b/flang/test/Lower/OpenACC/acc-reduction-maxmin.f90 index cd6e3fd2fb07b..bac76bb1dd202 100644 --- a/flang/test/Lower/OpenACC/acc-reduction-maxmin.f90 +++ b/flang/test/Lower/OpenACC/acc-reduction-maxmin.f90 @@ -58,40 +58,40 @@ end subroutine acc_array_reduction_min ! EXTREMUM-LABEL: acc.reduction.recipe @reduction_minimumf_ref_10xf32 : !fir.ref> reduction_operator init { ! EXTREMUM: } combiner { ! EXTREMUM: fir.do_loop -! EXTREMUM: %[[MINIMUMF_0:.*]] = arith.minimumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMUM-LABEL: acc.reduction.recipe @reduction_minimumf_ref_f32 : !fir.ref reduction_operator init { ! EXTREMUM: %[[CST:.*]] = arith.constant 3.40282347E+38 : f32 ! EXTREMUM: } combiner { -! EXTREMUM: %[[MINIMUMF_0:.*]] = arith.minimumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMUM-LABEL: acc.reduction.recipe @reduction_maximumf_ref_10xf32 : !fir.ref> reduction_operator init { ! EXTREMUM: } combiner { ! EXTREMUM: fir.do_loop -! EXTREMUM: %[[MAXIMUMF_0:.*]] = arith.maximumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMUM-LABEL: acc.reduction.recipe @reduction_maximumf_ref_f32 : !fir.ref reduction_operator init { ! EXTREMUM-LABEL: } combiner { -! EXTREMUM: %[[MAXIMUMF_0:.*]] = arith.maximumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMENUM-LABEL: acc.reduction.recipe @reduction_minnumf_ref_10xf32 : !fir.ref> reduction_operator init { ! EXTREMENUM: } combiner { ! EXTREMENUM: fir.do_loop -! EXTREMENUM: %[[MINNUMF_0:.*]] = arith.minnumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMENUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMENUM-LABEL: acc.reduction.recipe @reduction_minnumf_ref_f32 : !fir.ref reduction_operator init { ! EXTREMENUM: %[[CST:.*]] = arith.constant 3.40282347E+38 : f32 ! EXTREMENUM: } combiner { -! EXTREMENUM: %[[MINNUMF_0:.*]] = arith.minnumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMENUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMENUM-LABEL: acc.reduction.recipe @reduction_maxnumf_ref_10xf32 : !fir.ref> reduction_operator init { ! EXTREMENUM: } combiner { ! EXTREMENUM: fir.do_loop -! EXTREMENUM: %[[MAXNUMF_0:.*]] = arith.maxnumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMENUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMENUM-LABEL: acc.reduction.recipe @reduction_maxnumf_ref_f32 : !fir.ref reduction_operator init { ! EXTREMENUM-LABEL: } combiner { -! EXTREMENUM: %[[MAXNUMF_0:.*]] = arith.maxnumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMENUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! PORTABLE-NANNSZ-LABEL: acc.reduction.recipe @reduction_min_ref_10xf32 : !fir.ref> reduction_operator init { ! PORTABLE-NANNSZ: } combiner { diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90 index aa79a3789a009..fce9d0e2ff54d 100644 --- a/flang/test/Lower/OpenACC/acc-reduction.f90 +++ b/flang/test/Lower/OpenACC/acc-reduction.f90 @@ -1,7 +1,6 @@ ! This test checks lowering of OpenACC reduction clause. ! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s -! RUN: bbc -fopenacc -emit-hlfir %s -o - -openacc-use-reduction-combine | FileCheck -check-prefix=ACC_COMBINE %s ! CHECK-LABEL: acc.reduction.recipe @reduction_lor_ref_box_heap_l32 : !fir.ref>>> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>): @@ -320,10 +319,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_9]] to %[[CONSTANT_5]] step %[[CONSTANT_9]] unordered { ! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_4:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_4]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_2]] into %[[DESIGNATE_3]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.box> ! CHECK: } @@ -438,10 +434,7 @@ ! CHECK: %[[SUBI_1:.*]] = arith.subi %[[BOX_DIMS_3]]#0, %[[CONSTANT_6]] : index ! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[SUBI_1]] : index ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_1]]) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDI_2:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_2]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.box> @@ -523,10 +516,7 @@ ! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_17]] to %[[CONSTANT_6]] step %[[CONSTANT_17]] unordered { ! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref ! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_2]] into %[[DESIGNATE_3]] : !fir.ref ! CHECK: } ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> @@ -583,10 +573,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_10]] to %[[CONSTANT_5]] step %[[CONSTANT_10]] unordered { ! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_2]] into %[[DESIGNATE_3]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -609,10 +596,7 @@ ! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.ptr ! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> ! CHECK: %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box>) -> !fir.ptr -! CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.ptr -! CHECK: %[[LOAD_3:.*]] = fir.load %[[BOX_ADDR_1]] : !fir.ptr -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[LOAD_2]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[BOX_ADDR_1]] : i32, !fir.ptr +! CHECK: acc.reduction_combine %[[BOX_ADDR_0]] into %[[BOX_ADDR_1]] : !fir.ptr ! CHECK: acc.yield %[[VAL_0]] : !fir.ref>> ! CHECK-LABEL: } destroy { @@ -642,10 +626,7 @@ ! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.heap ! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> ! CHECK: %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box>) -> !fir.heap -! CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.heap -! CHECK: %[[LOAD_3:.*]] = fir.load %[[BOX_ADDR_1]] : !fir.heap -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[LOAD_2]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[BOX_ADDR_1]] : i32, !fir.heap +! CHECK: acc.reduction_combine %[[BOX_ADDR_0]] into %[[BOX_ADDR_1]] : !fir.heap ! CHECK: acc.yield %[[VAL_0]] : !fir.ref>> ! CHECK-LABEL: } destroy { @@ -669,10 +650,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> -! CHECK: %[[MULC_0:.*]] = fir.mulc %[[LOAD_1]], %[[LOAD_0]] {fastmath = #arith.fastmath} : complex -! CHECK: hlfir.assign %[[MULC_0]] to %[[VAL_0]] : complex, !fir.ref> +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref> ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -689,10 +667,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> -! CHECK: %[[ADDC_0:.*]] = fir.addc %[[LOAD_1]], %[[LOAD_0]] {fastmath = #arith.fastmath} : complex -! CHECK: hlfir.assign %[[ADDC_0]] to %[[VAL_0]] : complex, !fir.ref> +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref> ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -769,10 +744,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[XORI_0:.*]] = arith.xori %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[XORI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -785,10 +757,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[ORI_0:.*]] = arith.ori %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ORI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -801,10 +770,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[ANDI_0:.*]] = arith.andi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ANDI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1054,10 +1020,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[MULF_0:.*]] = arith.mulf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 -! CHECK: hlfir.assign %[[MULF_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -1071,10 +1034,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[MULF_0:.*]] = arith.mulf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 -! CHECK: hlfir.assign %[[MULF_0]] to %[[VAL_0]] : f32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1104,10 +1064,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[MULI_0:.*]] = arith.muli %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[MULI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -1121,10 +1078,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[MULI_0:.*]] = arith.muli %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[MULI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1154,10 +1108,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDF_0:.*]] = arith.addf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 -! CHECK: hlfir.assign %[[ADDF_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -1171,10 +1122,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[ADDF_0:.*]] = arith.addf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 -! CHECK: hlfir.assign %[[ADDF_0]] to %[[VAL_0]] : f32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1218,10 +1166,7 @@ ! CHECK: fir.do_loop %[[VAL_4:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_0]] step %[[CONSTANT_6]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_4]], %[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_4]], %[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: } ! CHECK: } @@ -1261,10 +1206,7 @@ ! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_0]] step %[[CONSTANT_4]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> @@ -1296,10 +1238,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -1319,10 +1258,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1884,111 +1820,3 @@ subroutine acc_reduction_logical_allocatable(l) ! CHECK-LABEL: func.func @_QPacc_reduction_logical_allocatable( ! CHECK: %[[REDUCTION_0:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref>>>) recipe(@reduction_lor_ref_box_heap_l32) -> !fir.ref>>> {name = "l"} ! CHECK: acc.parallel reduction(%[[REDUCTION_0]] : !fir.ref>>>) - -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_lor_ref_box_heap_l32 : !fir.ref>>> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_box_UxUxf32 : !fir.box> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_box_ptr_Uxf32 : !fir.ref>>> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_box_heap_Uxf32 : !fir.ref>>> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine - -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_section_lb1.ub3_box_Uxi32 : !fir.box> reduction_operator init { -! ACC_COMBINE-LABEL: } combiner { -! ACC_COMBINE: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): -! ACC_COMBINE: %[[CONSTANT_0:.*]] = arith.constant 1 : index -! ACC_COMBINE: %[[CONSTANT_1:.*]] = arith.constant 1 : index -! ACC_COMBINE: %[[CONSTANT_2:.*]] = arith.constant 3 : index -! ACC_COMBINE: %[[CONSTANT_3:.*]] = arith.constant 0 : index -! ACC_COMBINE: %[[CONSTANT_4:.*]] = arith.constant 2 : index -! ACC_COMBINE: %[[CONSTANT_5:.*]] = arith.constant 3 : index -! ACC_COMBINE: %[[CONSTANT_6:.*]] = arith.constant true -! ACC_COMBINE: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]] : (index) -> !fir.shape<1> -! ACC_COMBINE: %[[CONSTANT_7:.*]] = arith.constant 0 : index -! ACC_COMBINE: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_7]] : (!fir.box>, index) -> (index, index, index) -! ACC_COMBINE: %[[ADDI_0:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_1]] : index -! ACC_COMBINE: %[[ADDI_1:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_2]] : index -! ACC_COMBINE: %[[CONSTANT_8:.*]] = arith.constant 0 : index -! ACC_COMBINE: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_8]] : (!fir.box>, index) -> (index, index, index) -! ACC_COMBINE: %[[ADDI_2:.*]] = arith.addi %[[BOX_DIMS_1]]#0, %[[CONSTANT_1]] : index -! ACC_COMBINE: %[[ADDI_3:.*]] = arith.addi %[[BOX_DIMS_1]]#0, %[[CONSTANT_2]] : index -! ACC_COMBINE: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[ADDI_2]]:%[[ADDI_3]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> -! ACC_COMBINE: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_0]]:%[[ADDI_1]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> -! ACC_COMBINE: %[[CONSTANT_9:.*]] = arith.constant 1 : index -! ACC_COMBINE: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_9]] to %[[CONSTANT_5]] step %[[CONSTANT_9]] unordered { -! ACC_COMBINE: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref -! ACC_COMBINE: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref -! ACC_COMBINE: acc.reduction_combine %[[DESIGNATE_2]] into %[[DESIGNATE_3]] : !fir.ref -! ACC_COMBINE: } -! ACC_COMBINE: acc.yield %[[VAL_0]] : !fir.box> -! ACC_COMBINE: } - - -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_box_Uxf32 : !fir.box> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_box_Uxi32 : !fir.box> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_section_lb0.ub9xlb0.ub19_ref_10x20xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_section_lb10.ub19_ref_100xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_box_ptr_i32 : !fir.ref>> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ptr -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_box_heap_i32 : !fir.ref>> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.heap -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_z32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref> -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_z32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref> -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_neqv_ref_l32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_eqv_ref_l32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_lor_ref_l32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_land_ref_l32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_xor_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_ior_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_iand_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_100xf32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_f32 : !fir.ref reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_100x10xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_min_ref_100x10xf32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_min_ref_f32 : !fir.ref reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_min_ref_100xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_min_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_100xf32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_f32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_100xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_100xf32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_f32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_100x10x2xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_100x10xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_100xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref diff --git a/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 b/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 index 0f00e06dfdb1a..eb72b9b9197b9 100644 --- a/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 +++ b/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 @@ -12,7 +12,7 @@ !CHECK: omp.parallel { !CHECK: %[[A_TP:.*]] = omp.threadprivate %[[A_DECL]]#0 : !fir.ref -> !fir.ref !CHECK: %[[A_TP_DECL:.*]]:2 = hlfir.declare %[[A_TP]] {uniq_name = "_QFsub1Ea"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: %[[TID:.*]] = fir.call @omp_get_thread_num() proc_attrs fastmath : () -> i32 +!CHECK: %[[TID:.*]] = fir.call @omp_get_thread_num() proc_attrs fastmath : () -> i32 !CHECK: hlfir.assign %[[TID]] to %[[A_TP_DECL]]#0 : i32, !fir.ref !CHECK: omp.terminator !CHECK: } @@ -43,7 +43,7 @@ subroutine sub1() !CHECK: %[[A_TP_ADDR:.*]] = fir.coordinate_of %[[BLK_TP]], %c0_1 : (!fir.ref>, index) -> !fir.ref !CHECK: %[[A_TP_ADDR_CVT:.*]] = fir.convert %[[A_TP_ADDR]] : (!fir.ref) -> !fir.ref !CHECK: %[[A_TP_DECL:.*]]:2 = hlfir.declare %[[A_TP_ADDR_CVT]] storage(%[[BLK_TP]][0]) {uniq_name = "_QFsub2Ea"} : (!fir.ref, !fir.ref>) -> (!fir.ref, !fir.ref) -!CHECK: %[[TID:.*]] = fir.call @omp_get_thread_num() proc_attrs fastmath : () -> i32 +!CHECK: %[[TID:.*]] = fir.call @omp_get_thread_num() proc_attrs fastmath : () -> i32 !CHECK: hlfir.assign %[[TID]] to %[[A_TP_DECL]]#0 : i32, !fir.ref !CHECK: omp.terminator !CHECK: } diff --git a/flang/test/Semantics/OpenMP/ordered02.f90 b/flang/test/Semantics/OpenMP/ordered02.f90 index ed320c82a9794..649e008f7cb54 100644 --- a/flang/test/Semantics/OpenMP/ordered02.f90 +++ b/flang/test/Semantics/OpenMP/ordered02.f90 @@ -143,4 +143,40 @@ subroutine sub1() !$omp end ordered end do !$omp end target parallel do + + ! THREADS+SIMD inside a plain SIMD (not DO SIMD) region must be rejected + !$omp simd + do i = 1, N + !ERROR: An ORDERED directive with SIMD and THREADS clauses must be closely nested in a worksharing-loop SIMD region + !$omp ordered threads simd + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end simd + + ! THREADS+SIMD inside a DO SIMD region is valid + !$omp do simd ordered + do i = 1, N + !$omp ordered threads simd + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end do simd end + +! No diagnostic when ORDERED THREADS SIMD is in a called routine (enclosing +! DO SIMD region is not visible to the static checker). +subroutine contains_ordered_threads_simd() + !$omp ordered threads simd + !$omp end ordered +end subroutine + +subroutine sub2() + integer :: i, N = 10 + external :: contains_ordered_threads_simd + !$omp do simd ordered + do i = 1, N + call contains_ordered_threads_simd() + end do + !$omp end do simd +end subroutine diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp index 88fa43c748e2f..124c566bc6b13 100644 --- a/flang/tools/bbc/bbc.cpp +++ b/flang/tools/bbc/bbc.cpp @@ -428,6 +428,27 @@ static llvm::LogicalResult convertFortranSourceToMLIR( // run semantics auto &parseTree = *parsing.parseTree(); + std::vector implicitUseModuleNames; + for (const std::string &module : implicitUseModules) { + bool moduleIsDefinedInInput{false}; + for (const Fortran::parser::ProgramUnit &unit : parseTree.v) { + if (const auto *indirectModule{std::get_if< + Fortran::common::Indirection>( + &unit.u)}) { + const auto &moduleStmt{ + std::get>( + indirectModule->value().t)}; + if (moduleStmt.statement.v.source.ToString() == module) { + moduleIsDefinedInInput = true; + break; + } + } + } + if (!moduleIsDefinedInInput) { + implicitUseModuleNames.push_back(module); + } + } + semanticsContext.set_implicitUseModules(implicitUseModuleNames); Fortran::semantics::Semantics semantics(semanticsContext, parseTree); semantics.Perform(); semantics.EmitMessages(llvm::errs()); @@ -695,7 +716,6 @@ int main(int argc, char **argv) { .set_moduleFileSuffix(moduleSuffix) .set_searchDirectories(includeDirs) .set_intrinsicModuleDirectories(intrinsicIncludeDirs) - .set_implicitUseModules(implicitUseModules) .set_warnOnNonstandardUsage(warnStdViolation) .set_warningsAreErrors(warnIsError); diff --git a/flang/unittests/Optimizer/AliasAnalysisCacheTest.cpp b/flang/unittests/Optimizer/AliasAnalysisCacheTest.cpp new file mode 100644 index 0000000000000..4d1abfff7e258 --- /dev/null +++ b/flang/unittests/Optimizer/AliasAnalysisCacheTest.cpp @@ -0,0 +1,107 @@ +//===- AliasAnalysisCacheTest.cpp -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Unit tests for the opt-in getSource() memoization cache on +// fir::AliasAnalysis. The cache is off by default; when enabled it memoizes +// getSource() results for the lifetime of the analysis instance and is a +// frozen snapshot (no automatic invalidation). +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "flang/Optimizer/Analysis/AliasAnalysis.h" +#include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/Support/InitFIR.h" + +struct AliasAnalysisCacheTest : public testing::Test { +public: + void SetUp() override { + fir::support::loadDialects(context); + builder = std::make_unique(&context); + mlir::Location loc = builder->getUnknownLoc(); + + // Set up a module with a dummy function; insert into its entry block. + moduleOp = mlir::ModuleOp::create(*builder, loc); + builder->setInsertionPointToStart(moduleOp->getBody()); + mlir::func::FuncOp func = mlir::func::FuncOp::create(*builder, loc, + "alias_analysis_cache_tests", builder->getFunctionType({}, {})); + auto *entryBlock = func.addEntryBlock(); + builder->setInsertionPointToStart(entryBlock); + } + + mlir::Location getLoc() { return builder->getUnknownLoc(); } + + mlir::Value createAlloca() { + return fir::AllocaOp::create( + *builder, getLoc(), mlir::Float32Type::get(&context)); + } + + mlir::MLIRContext context; + std::unique_ptr builder; + mlir::OwningOpRef moduleOp; +}; + +// Caching is off by default: getSource() bypasses the cache, so nothing is +// memoized and the hit/miss counters stay at zero. +TEST_F(AliasAnalysisCacheTest, DisabledByDefault) { + mlir::Value a = createAlloca(); + fir::AliasAnalysis aa; + + (void)aa.getSource(a); + (void)aa.getSource(a); + + EXPECT_EQ(aa.getSourceCacheSizeForTesting(), 0u); + EXPECT_EQ(aa.getSourceCacheHitsForTesting(), 0u); + EXPECT_EQ(aa.getSourceCacheMissesForTesting(), 0u); +} + +// Once enabled, a query populates the cache (a miss) and a repeated query for +// the same value is served from it (a hit) without growing the cache. +TEST_F(AliasAnalysisCacheTest, FillAndHit) { + mlir::Value a = createAlloca(); + mlir::Value b = createAlloca(); + fir::AliasAnalysis aa; + aa.enableSourceCache(); + + (void)aa.getSource(a); + std::size_t sizeAfterFill = aa.getSourceCacheSizeForTesting(); + std::size_t missesAfterFill = aa.getSourceCacheMissesForTesting(); + EXPECT_GE(sizeAfterFill, 1u); + EXPECT_GE(missesAfterFill, 1u); + EXPECT_EQ(aa.getSourceCacheHitsForTesting(), 0u); + + // Repeating the top-level query is a single cache hit: it returns the + // memoized result without recomputing (and thus without new misses or + // entries), regardless of any recursive sub-queries the first call made. + (void)aa.getSource(a); + EXPECT_EQ(aa.getSourceCacheSizeForTesting(), sizeAfterFill); + EXPECT_EQ(aa.getSourceCacheMissesForTesting(), missesAfterFill); + EXPECT_EQ(aa.getSourceCacheHitsForTesting(), 1u); + + // A distinct value adds at least one new entry. + (void)aa.getSource(b); + EXPECT_GT(aa.getSourceCacheSizeForTesting(), sizeAfterFill); + EXPECT_GT(aa.getSourceCacheMissesForTesting(), missesAfterFill); +} + +// disableSourceCache() clears the entries and turns memoization off, so later +// queries bypass the cache and leave it empty. +TEST_F(AliasAnalysisCacheTest, DisableClearsAndBypasses) { + mlir::Value a = createAlloca(); + fir::AliasAnalysis aa; + aa.enableSourceCache(); + + (void)aa.getSource(a); + EXPECT_GE(aa.getSourceCacheSizeForTesting(), 1u); + + aa.disableSourceCache(); + EXPECT_EQ(aa.getSourceCacheSizeForTesting(), 0u); + + (void)aa.getSource(a); + EXPECT_EQ(aa.getSourceCacheSizeForTesting(), 0u); +} diff --git a/flang/unittests/Optimizer/CMakeLists.txt b/flang/unittests/Optimizer/CMakeLists.txt index 1697b64f12ed9..fc2badc59a083 100644 --- a/flang/unittests/Optimizer/CMakeLists.txt +++ b/flang/unittests/Optimizer/CMakeLists.txt @@ -40,6 +40,7 @@ add_flang_unittest(FlangOptimizerTests Builder/Runtime/TransformationalTest.cpp OpenACC/FIROpenACCPointerLikeTypeInterfaceTest.cpp OpenACC/FIROpenACCSupportAnalysisTest.cpp + AliasAnalysisCacheTest.cpp FIRCallInterfaceTest.cpp FIRContextTest.cpp FIRTypesTest.cpp diff --git a/libc/config/baremetal/config.json b/libc/config/baremetal/config.json index 5ccc327693084..1c52cd0093e1c 100644 --- a/libc/config/baremetal/config.json +++ b/libc/config/baremetal/config.json @@ -13,6 +13,9 @@ "LIBC_CONF_PRINTF_DISABLE_FIXED_POINT": { "value": true }, + "LIBC_CONF_PRINTF_DISABLE_FLOAT": { + "value": true + }, "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": { "value": true }, @@ -30,12 +33,6 @@ }, "LIBC_COPT_PRINTF_DISABLE_BITINT": { "value": true - }, - "LIBC_CONF_PRINTF_MODULAR": { - "value": true - }, - "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_FLOAT320": { - "value": true } }, "scanf": { diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt index 3558019e50608..5ad356f89d913 100644 --- a/libc/hdr/CMakeLists.txt +++ b/libc/hdr/CMakeLists.txt @@ -231,6 +231,15 @@ add_proxy_header_library( libc.include.llvm-libc-macros.sys_ptrace_macros ) +add_proxy_header_library( + sys_time_macros + HDRS + sys_time_macros.h + FULL_BUILD_DEPENDS + libc.include.sys_time + libc.include.llvm-libc-macros.sys_time_macros +) + add_header_library(unistd_overlay HDRS unistd_overlay.h) add_proxy_header_library( unistd_macros diff --git a/libc/hdr/sys_time_macros.h b/libc/hdr/sys_time_macros.h new file mode 100644 index 0000000000000..94fb829783b64 --- /dev/null +++ b/libc/hdr/sys_time_macros.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Proxy header for sys/time.h macros. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_HDR_SYS_TIME_MACROS_H +#define LLVM_LIBC_HDR_SYS_TIME_MACROS_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-macros/sys-time-macros.h" + +#else // Overlay mode + +#include + +#endif // LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_SYS_TIME_MACROS_H diff --git a/libc/include/llvm-libc-macros/linux/sys-time-macros.h b/libc/include/llvm-libc-macros/linux/sys-time-macros.h index e97819594adcb..677eab50ba098 100644 --- a/libc/include/llvm-libc-macros/linux/sys-time-macros.h +++ b/libc/include/llvm-libc-macros/linux/sys-time-macros.h @@ -9,6 +9,11 @@ #ifndef LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H #define LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H +// Timer types for setitimer(2). +#define ITIMER_REAL 0 +#define ITIMER_VIRTUAL 1 +#define ITIMER_PROF 2 + // Add two timevals and put the result in timeval_ptr_result. If the resulting // usec value is greater than 999,999 then the microseconds are turned into full // seconds (1,000,000 is subtracted from usec and 1 is added to sec). diff --git a/libc/include/sys/time.yaml b/libc/include/sys/time.yaml index f1dcdff354652..5869646a003cd 100644 --- a/libc/include/sys/time.yaml +++ b/libc/include/sys/time.yaml @@ -2,6 +2,12 @@ header: sys/time.h standards: - posix macros: + - macro_name: ITIMER_REAL + macro_header: sys-time-macros.h + - macro_name: ITIMER_VIRTUAL + macro_header: sys-time-macros.h + - macro_name: ITIMER_PROF + macro_header: sys-time-macros.h - macro_name: timeradd macro_header: sys-time-macros.h types: diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt index a3cdb17e9ea5c..27df4c3f22afb 100644 --- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt @@ -1,3 +1,18 @@ +add_header_library( + alarm + HDRS + alarm.h + DEPENDS + libc.hdr.sys_time_macros + libc.hdr.types.struct_itimerval + libc.include.sys_syscall + libc.src.__support.OSUtil.linux.syscall_wrappers.setitimer + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config +) + add_header_library( getrandom HDRS @@ -245,6 +260,34 @@ add_header_library( libc.include.sys_syscall ) +add_header_library( + getitimer + HDRS + getitimer.h + DEPENDS + libc.hdr.types.struct_itimerval + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config +) + +add_header_library( + setitimer + HDRS + setitimer.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.types.struct_itimerval + libc.include.sys_syscall + libc.src.__support.CPP.limits + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config +) + add_header_library( setsockopt HDRS diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h new file mode 100644 index 0000000000000..754b1d273acba --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Syscall wrapper for alarm. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H + +#include "hdr/sys_time_macros.h" +#include "hdr/types/struct_itimerval.h" +#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked +#include "src/__support/OSUtil/linux/syscall_wrappers/setitimer.h" +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr alarm(unsigned int seconds) { +#ifdef SYS_alarm + return syscall_checked(SYS_alarm, seconds); +#elif defined(SYS_setitimer) + struct itimerval old_itv; + struct itimerval itv = {}; + itv.it_value.tv_sec = seconds; + ErrorOr ret = linux_syscalls::setitimer(ITIMER_REAL, &itv, &old_itv); + if (!ret) + return Error(ret.error()); + return static_cast(old_itv.it_value.tv_sec + + (old_itv.it_value.tv_usec > 0 ? 1 : 0)); +#else +#error "alarm implementation not available for this architecture" +#endif +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h new file mode 100644 index 0000000000000..86211700ac688 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Syscall wrapper for getitimer. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H + +#include "hdr/types/struct_itimerval.h" +#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr getitimer(int which, struct itimerval *curr_val) { + if constexpr (sizeof(time_t) == sizeof(long)) { + return syscall_checked(SYS_getitimer, which, curr_val); + } else { + // There is no SYS_getitimer_time64 call, so we can't use time_t directly, + // and need to convert from long first. + long curr_val32[4]; + long *curr_val32_ptr = curr_val ? curr_val32 : nullptr; + + ErrorOr ret = + syscall_checked(SYS_getitimer, which, curr_val32_ptr); + + if (!ret) + return ret; + + if (curr_val) { + curr_val->it_interval.tv_sec = curr_val32[0]; + curr_val->it_interval.tv_usec = curr_val32[1]; + curr_val->it_value.tv_sec = curr_val32[2]; + curr_val->it_value.tv_usec = curr_val32[3]; + } + return ret; + } +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h new file mode 100644 index 0000000000000..82cb1d84b8d81 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Syscall wrapper for setitimer. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H + +#include "hdr/errno_macros.h" +#include "hdr/types/struct_itimerval.h" +#include "src/__support/CPP/limits.h" +#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr setitimer(int which, const struct itimerval *new_val, + struct itimerval *old_val) { + if constexpr (sizeof(time_t) == sizeof(long)) { + return syscall_checked(SYS_setitimer, which, new_val, old_val); + } else { + // There is no SYS_setitimer_time64 call, so we can't use time_t directly, + // and need to convert it to long first. + long old_val32[4]; + long *old_val32_ptr = old_val ? old_val32 : nullptr; + long new_val32[4]; + long *new_val32_ptr = nullptr; + + if (new_val) { + // Check for overflow before casting to 32-bit long. We'll let the kernel + // do the final validation. We're just making sure the truncation does not + // change the value. + auto fits_long = [](auto val) { + return val <= cpp::numeric_limits::max() && + val >= cpp::numeric_limits::min(); + }; + if (!fits_long(new_val->it_interval.tv_sec) || + !fits_long(new_val->it_value.tv_sec) || + !fits_long(new_val->it_interval.tv_usec) || + !fits_long(new_val->it_value.tv_usec)) { + return Error(EINVAL); + } + + new_val32[0] = static_cast(new_val->it_interval.tv_sec); + new_val32[1] = static_cast(new_val->it_interval.tv_usec); + new_val32[2] = static_cast(new_val->it_value.tv_sec); + new_val32[3] = static_cast(new_val->it_value.tv_usec); + new_val32_ptr = new_val32; + } + + ErrorOr ret = syscall_checked(SYS_setitimer, which, new_val32_ptr, + old_val32_ptr); + + if (!ret) + return ret; + + if (old_val) { + old_val->it_interval.tv_sec = old_val32[0]; + old_val->it_interval.tv_usec = old_val32[1]; + old_val->it_value.tv_sec = old_val32[2]; + old_val->it_value.tv_usec = old_val32[3]; + } + return ret; + } +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H diff --git a/libc/src/sys/time/linux/CMakeLists.txt b/libc/src/sys/time/linux/CMakeLists.txt index 60fbd14f73174..e74269d721c56 100644 --- a/libc/src/sys/time/linux/CMakeLists.txt +++ b/libc/src/sys/time/linux/CMakeLists.txt @@ -24,9 +24,10 @@ add_entrypoint_object( ../setitimer.h DEPENDS libc.hdr.types.struct_itimerval - libc.include.sys_syscall + libc.src.__support.OSUtil.linux.syscall_wrappers.setitimer libc.src.__support.OSUtil.osutil libc.src.__support.common + libc.src.__support.macros.config libc.src.errno.errno ) @@ -38,8 +39,9 @@ add_entrypoint_object( ../getitimer.h DEPENDS libc.hdr.types.struct_itimerval - libc.include.sys_syscall + libc.src.__support.OSUtil.linux.syscall_wrappers.getitimer libc.src.__support.OSUtil.osutil libc.src.__support.common + libc.src.__support.macros.config libc.src.errno.errno ) diff --git a/libc/src/sys/time/linux/getitimer.cpp b/libc/src/sys/time/linux/getitimer.cpp index 2a40491bc95fb..f875bc9b13b7e 100644 --- a/libc/src/sys/time/linux/getitimer.cpp +++ b/libc/src/sys/time/linux/getitimer.cpp @@ -7,38 +7,17 @@ //===----------------------------------------------------------------------===// #include "src/sys/time/getitimer.h" -#include "hdr/types/struct_itimerval.h" -#include "src/__support/OSUtil/syscall.h" +#include "src/__support/OSUtil/linux/syscall_wrappers/getitimer.h" #include "src/__support/common.h" #include "src/__support/libc_errno.h" -#include +#include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) { - long ret = 0; - if constexpr (sizeof(time_t) > sizeof(long)) { - // There is no SYS_getitimer_time64 call, so we can't use time_t directly. - if (curr_value) { - long curr_value32[4]; - ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, - curr_value32); - if (!ret) { - curr_value->it_interval.tv_sec = curr_value32[0]; - curr_value->it_interval.tv_usec = curr_value32[1]; - curr_value->it_value.tv_sec = curr_value32[2]; - curr_value->it_value.tv_usec = curr_value32[3]; - } - } else { - ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, nullptr); - } - } else { - ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value); - } - - // On failure, return -1 and set errno. - if (ret < 0) { - libc_errno = static_cast(-ret); + ErrorOr ret = linux_syscalls::getitimer(which, curr_value); + if (!ret) { + libc_errno = ret.error(); return -1; } return 0; diff --git a/libc/src/sys/time/linux/setitimer.cpp b/libc/src/sys/time/linux/setitimer.cpp index 2c2f0d7198204..07cb9180a7f7e 100644 --- a/libc/src/sys/time/linux/setitimer.cpp +++ b/libc/src/sys/time/linux/setitimer.cpp @@ -6,62 +6,19 @@ // //===----------------------------------------------------------------------===// #include "src/sys/time/setitimer.h" -#include "hdr/errno_macros.h" -#include "hdr/types/struct_itimerval.h" -#include "src/__support/CPP/limits.h" -#include "src/__support/OSUtil/syscall.h" +#include "src/__support/OSUtil/linux/syscall_wrappers/setitimer.h" #include "src/__support/common.h" #include "src/__support/libc_errno.h" -#include +#include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, setitimer, (int which, const struct itimerval *new_value, struct itimerval *old_value)) { - long ret = 0; - if constexpr (sizeof(time_t) > sizeof(long)) { - // There is no SYS_setitimer_time64 call, so we can't use time_t directly, - // and need to convert it to long first. - long old_value32[4]; - long *old_value32_ptr = old_value ? old_value32 : nullptr; - - if (new_value) { - // Check for overflow before casting to 32-bit long. - if (new_value->it_interval.tv_sec > cpp::numeric_limits::max() || - new_value->it_interval.tv_sec < cpp::numeric_limits::min() || - new_value->it_value.tv_sec > cpp::numeric_limits::max() || - new_value->it_value.tv_sec < cpp::numeric_limits::min()) { - libc_errno = EOVERFLOW; - return -1; - } - - long new_value32[4] = {static_cast(new_value->it_interval.tv_sec), - static_cast(new_value->it_interval.tv_usec), - static_cast(new_value->it_value.tv_sec), - static_cast(new_value->it_value.tv_usec)}; - - ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, - new_value32, old_value32_ptr); - } else { - ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, nullptr, - old_value32_ptr); - } - - if (!ret && old_value) { - old_value->it_interval.tv_sec = old_value32[0]; - old_value->it_interval.tv_usec = old_value32[1]; - old_value->it_value.tv_sec = old_value32[2]; - old_value->it_value.tv_usec = old_value32[3]; - } - } else { - ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, new_value, - old_value); - } - - // On failure, return -1 and set errno. - if (ret < 0) { - libc_errno = static_cast(-ret); + ErrorOr ret = linux_syscalls::setitimer(which, new_value, old_value); + if (!ret) { + libc_errno = ret.error(); return -1; } return 0; diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt index af385e9bbed72..168b61bede853 100644 --- a/libc/src/unistd/linux/CMakeLists.txt +++ b/libc/src/unistd/linux/CMakeLists.txt @@ -5,9 +5,7 @@ add_entrypoint_object( HDRS ../alarm.h DEPENDS - libc.hdr.types.struct_itimerval - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil + libc.src.__support.OSUtil.linux.syscall_wrappers.alarm libc.src.__support.common libc.src.__support.macros.config ) diff --git a/libc/src/unistd/linux/alarm.cpp b/libc/src/unistd/linux/alarm.cpp index f849e487a3f96..bc2febff0248f 100644 --- a/libc/src/unistd/linux/alarm.cpp +++ b/libc/src/unistd/linux/alarm.cpp @@ -12,50 +12,17 @@ //===----------------------------------------------------------------------===// #include "src/unistd/alarm.h" - -#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/OSUtil/linux/syscall_wrappers/alarm.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include // For syscall numbers. - -#ifndef SYS_alarm -#include "hdr/types/struct_itimerval.h" -#endif - namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(unsigned int, alarm, (unsigned int seconds)) { -#ifdef SYS_alarm - return static_cast( - LIBC_NAMESPACE::syscall_impl(SYS_alarm, seconds)); -#elif defined(SYS_setitimer) - // On 32-bit architectures with 64-bit time_t, SYS_setitimer still expects - // 32-bit fields. We must convert itimerval to use 32-bit fields. - if constexpr (sizeof(time_t) > sizeof(long)) { - long itv32[4] = {0, 0, static_cast(seconds), 0}; - long old_itv32[4]; - long ret = LIBC_NAMESPACE::syscall_impl( - SYS_setitimer, 0 /* ITIMER_REAL */, itv32, old_itv32); - if (ret < 0) - return 0; - return static_cast(old_itv32[2] + (old_itv32[3] > 0 ? 1 : 0)); - } else { - struct itimerval itv, old_itv; - itv.it_interval.tv_sec = 0; - itv.it_interval.tv_usec = 0; - itv.it_value.tv_sec = seconds; - itv.it_value.tv_usec = 0; - long ret = LIBC_NAMESPACE::syscall_impl( - SYS_setitimer, 0 /* ITIMER_REAL */, &itv, &old_itv); - if (ret < 0) - return 0; - return static_cast(old_itv.it_value.tv_sec + - (old_itv.it_value.tv_usec > 0 ? 1 : 0)); - } -#else -#error "alarm implementation not available for this architecture" -#endif + ErrorOr ret = linux_syscalls::alarm(seconds); + if (!ret) + return 0; + return ret.value(); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt index 44b9fea16a40d..1f28b99601e61 100644 --- a/libc/test/src/sys/socket/linux/CMakeLists.txt +++ b/libc/test/src/sys/socket/linux/CMakeLists.txt @@ -129,10 +129,10 @@ add_libc_unittest( libc.src.sys.socket.socket libc.src.sys.socket.socketpair libc.src.sys.socket.recv - libc.src.time.clock_gettime libc.src.unistd.close libc.src.unistd.pipe libc.src.__support.CPP.scope + libc.src.__support.time.clock_gettime libc.test.UnitTest.ErrnoCheckingTest libc.test.UnitTest.ErrnoSetterMatcher ) diff --git a/libc/test/src/sys/socket/linux/socketopt_test.cpp b/libc/test/src/sys/socket/linux/socketopt_test.cpp index 3af47c3f18a7d..8fd03c2cf24d4 100644 --- a/libc/test/src/sys/socket/linux/socketopt_test.cpp +++ b/libc/test/src/sys/socket/linux/socketopt_test.cpp @@ -11,13 +11,12 @@ #include "hdr/types/struct_linger.h" #include "hdr/types/struct_timespec.h" #include "hdr/types/struct_timeval.h" +#include "src/__support/time/clock_gettime.h" #include "src/sys/socket/getsockopt.h" #include "src/sys/socket/recv.h" #include "src/sys/socket/setsockopt.h" #include "src/sys/socket/socket.h" #include "src/sys/socket/socketpair.h" -#include "src/time/clock_gettime.h" - #include "src/unistd/close.h" #include "src/unistd/pipe.h" @@ -145,11 +144,13 @@ TEST_F(LlvmLibcSocketOptTest, ReceiveTimeout) { char buffer[10]; struct timespec start, end; - ASSERT_EQ(LIBC_NAMESPACE::clock_gettime(CLOCK_MONOTONIC, &start), 0); + ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &start) + .has_value()); // Read/recv on empty socket should block for ~1s and fail with EAGAIN. ASSERT_THAT(LIBC_NAMESPACE::recv(sv[0], buffer, sizeof(buffer), 0), Fails(EAGAIN)); - ASSERT_EQ(LIBC_NAMESPACE::clock_gettime(CLOCK_MONOTONIC, &end), 0); + ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &end) + .has_value()); int64_t elapsed_seconds = end.tv_sec - start.tv_sec; int64_t elapsed_nseconds = end.tv_nsec - start.tv_nsec; diff --git a/libc/test/src/sys/time/CMakeLists.txt b/libc/test/src/sys/time/CMakeLists.txt index 2468b4ae2cc34..eb9753bb5bf2d 100644 --- a/libc/test/src/sys/time/CMakeLists.txt +++ b/libc/test/src/sys/time/CMakeLists.txt @@ -27,6 +27,7 @@ add_libc_unittest( SRCS setitimer_test.cpp DEPENDS + libc.hdr.sys_time_macros libc.include.signal libc.src.sys.time.setitimer libc.src.signal.sigaction @@ -44,6 +45,7 @@ add_libc_unittest( SRCS getitimer_test.cpp DEPENDS + libc.hdr.sys_time_macros libc.src.sys.time.getitimer libc.src.__support.common libc.src.errno.errno diff --git a/libc/test/src/sys/time/getitimer_test.cpp b/libc/test/src/sys/time/getitimer_test.cpp index c1d6f72701627..93d885760a5af 100644 --- a/libc/test/src/sys/time/getitimer_test.cpp +++ b/libc/test/src/sys/time/getitimer_test.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/sys_time_macros.h" #include "hdr/types/struct_itimerval.h" #include "src/sys/time/getitimer.h" #include "test/UnitTest/ErrnoCheckingTest.h" @@ -23,7 +24,7 @@ TEST_F(LlvmLibcSysTimeGetitimerTest, SmokeTest) { timer.it_interval.tv_sec = -1; timer.it_interval.tv_usec = -1; - ASSERT_THAT(LIBC_NAMESPACE::getitimer(0, &timer), + ASSERT_THAT(LIBC_NAMESPACE::getitimer(ITIMER_REAL, &timer), returns(EQ(0)).with_errno(EQ(0))); ASSERT_TRUE(timer.it_value.tv_sec == 0); diff --git a/libc/test/src/sys/time/setitimer_test.cpp b/libc/test/src/sys/time/setitimer_test.cpp index 115f9e662ed46..aa4feb6aace4d 100644 --- a/libc/test/src/sys/time/setitimer_test.cpp +++ b/libc/test/src/sys/time/setitimer_test.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/sys_time_macros.h" #include "hdr/types/struct_itimerval.h" #include "hdr/types/struct_sigaction.h" #include "src/signal/sigaction.h" @@ -37,7 +38,7 @@ TEST_F(LlvmLibcSysTimeSetitimerTest, SmokeTest) { timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; // One-shot timer - ASSERT_THAT(LIBC_NAMESPACE::setitimer(0, &timer, nullptr), + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), returns(EQ(0)).with_errno(EQ(0))); while (true) { @@ -49,9 +50,33 @@ TEST_F(LlvmLibcSysTimeSetitimerTest, SmokeTest) { } TEST_F(LlvmLibcSysTimeSetitimerTest, InvalidRetTest) { - struct itimerval timer; + struct itimerval timer = {}; // out of range timer type (which) ASSERT_THAT(LIBC_NAMESPACE::setitimer(99, &timer, nullptr), returns(NE(0)).with_errno(NE(0))); + + // invalid microseconds (>= 1000000) + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 1000000; + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), + returns(EQ(-1)).with_errno(EQ(EINVAL))); + + // negative microseconds + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = -1; + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), + returns(EQ(-1)).with_errno(EQ(EINVAL))); + + // Test 64-bit microsecond values that would truncate to a valid 32-bit value + // (< 1000000). 0x100000047, If truncated to 32-bit integer, becomes 0x47. + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 0x1'0000'0047; + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), + returns(EQ(-1)).with_errno(EQ(EINVAL))); + + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 0xffff'ffff'0000'0047; + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), + returns(EQ(-1)).with_errno(EQ(EINVAL))); } diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h index 8a34ebcc7bb90..757ba69cb17b4 100644 --- a/libcxx/include/__configuration/abi.h +++ b/libcxx/include/__configuration/abi.h @@ -88,15 +88,6 @@ # endif #endif -// TODO(LLVM 22): Remove this check -#if defined(_LIBCPP_ABI_NO_ITERATOR_BASES) && !defined(_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER) -# ifndef _LIBCPP_ONLY_NO_ITERATOR_BASES -# error "You probably want to define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER. This has been split out from" \ - " _LIBCPP_ABI_NO_ITERATOR_BASES to allow only removing the second iterator member, since they aren't really related." \ - "If you actually want this ABI configuration, please define _LIBCPP_ONLY_NO_ITERATOR_BASES instead." -# endif -#endif - // We had some bugs where we use [[no_unique_address]] together with construct_at, // which causes UB as the call on construct_at could write to overlapping subobjects // @@ -105,7 +96,7 @@ // // To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions. // The macro below is used for all classes whose ABI have changed as part of fixing these bugs. -#define _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS __attribute__((__abi_tag__("llvm18_nua"))) +#define _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG __attribute__((__abi_tag__("llvm18_nua"))) // [[msvc::no_unique_address]] seems to mostly affect empty classes, so the padding scheme for Itanium doesn't work. #if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING) diff --git a/libcxx/include/__cxx03/__configuration/abi.h b/libcxx/include/__cxx03/__configuration/abi.h index 81dd5b1c59610..56ebe520f65a0 100644 --- a/libcxx/include/__cxx03/__configuration/abi.h +++ b/libcxx/include/__cxx03/__configuration/abi.h @@ -121,16 +121,6 @@ # endif #endif -// We had some bugs where we use [[no_unique_address]] together with construct_at, -// which causes UB as the call on construct_at could write to overlapping subobjects -// -// https://github.com/llvm/llvm-project/issues/70506 -// https://github.com/llvm/llvm-project/issues/70494 -// -// To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions. -// The macro below is used for all classes whose ABI have changed as part of fixing these bugs. -#define _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS __attribute__((__abi_tag__("llvm18_nua"))) - // Changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's // within the bounds of the original container and asserts it on every dereference. // diff --git a/libcxx/include/__ranges/chunk_by_view.h b/libcxx/include/__ranges/chunk_by_view.h index 8007f76f0c1e6..07824d11e79be 100644 --- a/libcxx/include/__ranges/chunk_by_view.h +++ b/libcxx/include/__ranges/chunk_by_view.h @@ -54,7 +54,7 @@ namespace ranges { template , iterator_t<_View>> _Pred> requires view<_View> && is_object_v<_Pred> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS chunk_by_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG chunk_by_view : public view_interface> { _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; diff --git a/libcxx/include/__ranges/drop_while_view.h b/libcxx/include/__ranges/drop_while_view.h index ed5b91d99425f..caa24643b477f 100644 --- a/libcxx/include/__ranges/drop_while_view.h +++ b/libcxx/include/__ranges/drop_while_view.h @@ -48,7 +48,7 @@ namespace ranges { template requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS drop_while_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG drop_while_view : public view_interface> { public: _LIBCPP_HIDE_FROM_ABI drop_while_view() requires default_initializable<_View> && default_initializable<_Pred> diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h index 4612dc4a9ba1d..7ec53dac4a84f 100644 --- a/libcxx/include/__ranges/filter_view.h +++ b/libcxx/include/__ranges/filter_view.h @@ -54,7 +54,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template > _Pred> requires view<_View> && is_object_v<_Pred> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS filter_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG filter_view : public view_interface> { _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; diff --git a/libcxx/include/__ranges/repeat_view.h b/libcxx/include/__ranges/repeat_view.h index ae13af8761b89..48e8f70cc10c6 100644 --- a/libcxx/include/__ranges/repeat_view.h +++ b/libcxx/include/__ranges/repeat_view.h @@ -74,7 +74,7 @@ struct __fn; template requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> && (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>)) -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS repeat_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG repeat_view : public view_interface> { friend struct views::__take::__fn; friend struct views::__drop::__fn; class __iterator; diff --git a/libcxx/include/__ranges/single_view.h b/libcxx/include/__ranges/single_view.h index 213c507138e68..b86a8d6790b01 100644 --- a/libcxx/include/__ranges/single_view.h +++ b/libcxx/include/__ranges/single_view.h @@ -41,7 +41,7 @@ template template # endif requires is_object_v<_Tp> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS single_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG single_view : public view_interface> { _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Tp> __value_; public: diff --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h index f91dcfa95b9a5..0aee306807c8b 100644 --- a/libcxx/include/__ranges/take_while_view.h +++ b/libcxx/include/__ranges/take_while_view.h @@ -46,7 +46,7 @@ namespace ranges { template requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS take_while_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG take_while_view : public view_interface> { template class __sentinel; diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h index 1484be006e841..06ace86bbfafa 100644 --- a/libcxx/include/__ranges/transform_view.h +++ b/libcxx/include/__ranges/transform_view.h @@ -71,7 +71,7 @@ template template # endif requires __transform_view_constraints<_View, _Fn> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS transform_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG transform_view : public view_interface> { template class __iterator; template diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 422c98c300a1d..8226a7f87a119 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -153,7 +153,6 @@ class vector { __guard.__complete(); } -#if _LIBCPP_STD_VER >= 14 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a) : __layout_(__a) { auto __guard = std::__make_exception_guard(__destroy_vector(*this)); @@ -163,7 +162,6 @@ class vector { } __guard.__complete(); } -#endif _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(size_type __n, const value_type& __x) { auto __guard = std::__make_exception_guard(__destroy_vector(*this)); diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h index f73e086478a70..6dc904e6d3bd9 100644 --- a/libcxx/include/__vector/vector_bool.h +++ b/libcxx/include/__vector/vector_bool.h @@ -152,9 +152,7 @@ class vector { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector() { __destroy_vector (*this)(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n); -#if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n, const allocator_type& __a); -#endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v, const allocator_type& __a); @@ -605,7 +603,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n) } } -#if _LIBCPP_STD_VER >= 14 template _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n, const allocator_type& __a) : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { @@ -615,7 +612,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n, co __size_ = __n; } } -#endif template _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n, const value_type& __x) diff --git a/libcxx/include/deque b/libcxx/include/deque index 7aee552c63d37..5a4de99c7f143 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -40,7 +40,7 @@ public: deque() noexcept(is_nothrow_default_constructible::value); explicit deque(const allocator_type& a); explicit deque(size_type n); - explicit deque(size_type n, const allocator_type& a); // C++14 + explicit deque(size_type n, const allocator_type& a); deque(size_type n, const value_type& v); deque(size_type n, const value_type& v, const allocator_type& a); template @@ -644,9 +644,7 @@ public: } explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); -# if _LIBCPP_STD_VER >= 14 explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); -# endif _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0> @@ -1323,7 +1321,6 @@ deque<_Tp, _Allocator>::deque(size_type __n) : __start_(0), __size_(0) { __append(__n); } -# if _LIBCPP_STD_VER >= 14 template deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) { @@ -1331,7 +1328,6 @@ deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) if (__n > 0) __append(__n); } -# endif template deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) : __start_(0), __size_(0) { diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list index 6d86f7a8e5975..d963fea6084ca 100644 --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -37,7 +37,7 @@ public: noexcept(is_nothrow_default_constructible::value); explicit forward_list(const allocator_type& a); explicit forward_list(size_type n); - explicit forward_list(size_type n, const allocator_type& a); // C++14 + explicit forward_list(size_type n, const allocator_type& a); forward_list(size_type n, const value_type& v); forward_list(size_type n, const value_type& v, const allocator_type& a); template @@ -664,9 +664,7 @@ public: _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {} // = default; _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit forward_list(const allocator_type& __a); _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n); -# if _LIBCPP_STD_VER >= 14 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n, const allocator_type& __a); -# endif _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v); template <__enable_if_t<__is_allocator_v<_Alloc>, int> = 0> @@ -941,7 +939,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type } } -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __base_alloc) : __base(__base_alloc) { @@ -952,7 +949,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type } } } -# endif template _LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) { diff --git a/libcxx/include/list b/libcxx/include/list index 3223f25e1cfba..b4fb9191cd7f7 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -39,7 +39,7 @@ public: noexcept(is_nothrow_default_constructible::value); explicit list(const allocator_type& a); explicit list(size_type n); - explicit list(size_type n, const allocator_type& a); // C++14 + explicit list(size_type n, const allocator_type& a); list(size_type n, const value_type& value); list(size_type n, const value_type& value, const allocator_type& a); template @@ -708,9 +708,7 @@ public: _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {} _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(const allocator_type& __a) : __base(__a) {} _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n); -# if _LIBCPP_STD_VER >= 14 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n, const allocator_type& __a); -# endif _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x); template <__enable_if_t<__is_allocator_v<_Alloc>, int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI @@ -1066,13 +1064,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n) { # endif } -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : __base(__a) { for (; __n > 0; --__n) +# ifndef _LIBCPP_CXX03_LANG emplace_back(); -} +# else + push_back(value_type()); # endif +} template _LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) { diff --git a/libcxx/include/map b/libcxx/include/map index 8efe18fa3f839..d51daa128eada 100644 --- a/libcxx/include/map +++ b/libcxx/include/map @@ -84,12 +84,12 @@ public: constexpr map(initializer_list il, const key_compare& comp, const allocator_type& a); template constexpr map(InputIterator first, InputIterator last, const allocator_type& a) - : map(first, last, Compare(), a) {} // C++14 + : map(first, last, Compare(), a) {} template R> constexpr map(from_range_t, R&& rg, const Allocator& a)) : map(from_range, std::forward(rg), Compare(), a) { } // C++23 constexpr map(initializer_list il, const allocator_type& a) - : map(il, Compare(), a) {} // C++14 + : map(il, Compare(), a) {} constexpr ~map(); constexpr map& operator=(const map& m); @@ -368,12 +368,12 @@ public: const allocator_type& a); template multimap(InputIterator first, InputIterator last, const allocator_type& a) - : multimap(first, last, Compare(), a) {} // C++14 + : multimap(first, last, Compare(), a) {} template R> multimap(from_range_t, R&& rg, const Allocator& a)) : multimap(from_range, std::forward(rg), Compare(), a) { } // C++23 multimap(initializer_list il, const allocator_type& a) - : multimap(il, Compare(), a) {} // C++14 + : multimap(il, Compare(), a) {} ~multimap(); multimap& operator=(const multimap& m); @@ -1035,12 +1035,10 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : map(__f, __l, key_compare(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -1073,10 +1071,8 @@ public: insert(__il.begin(), __il.end()); } -# if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(initializer_list __il, const allocator_type& __a) : map(__il, key_compare(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map& operator=(initializer_list __il) { clear(); @@ -1817,12 +1813,10 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : multimap(__f, __l, key_compare(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -1856,11 +1850,9 @@ public: insert(__il.begin(), __il.end()); } -# if _LIBCPP_STD_VER >= 14 - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX26 multimap(initializer_list __il, const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + multimap(initializer_list __il, const allocator_type& __a) : multimap(__il, key_compare(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 multimap& operator=(initializer_list __il) { clear(); diff --git a/libcxx/include/set b/libcxx/include/set index 0409131ac6981..59aef4a42b428 100644 --- a/libcxx/include/set +++ b/libcxx/include/set @@ -71,12 +71,12 @@ public: const allocator_type& a); template set(InputIterator first, InputIterator last, const allocator_type& a) - : set(first, last, Compare(), a) {} // C++14 + : set(first, last, Compare(), a) {} template R> set(from_range_t, R&& rg, const Allocator& a)) : set(from_range, std::forward(rg), Compare(), a) { } // C++23 set(initializer_list il, const allocator_type& a) - : set(il, Compare(), a) {} // C++14 + : set(il, Compare(), a) {} ~set(); set& operator=(const set& s); @@ -316,12 +316,12 @@ public: const allocator_type& a); template multiset(InputIterator first, InputIterator last, const allocator_type& a) - : set(first, last, Compare(), a) {} // C++14 + : set(first, last, Compare(), a) {} template R> multiset(from_range_t, R&& rg, const Allocator& a)) : multiset(from_range, std::forward(rg), Compare(), a) { } // C++23 multiset(initializer_list il, const allocator_type& a) - : set(il, Compare(), a) {} // C++14 + : set(il, Compare(), a) {} ~multiset(); multiset& operator=(const multiset& s); @@ -653,12 +653,10 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 set(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : set(__f, __l, key_compare(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -695,10 +693,8 @@ public: insert(__il.begin(), __il.end()); } -# if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 set(initializer_list __il, const allocator_type& __a) : set(__il, key_compare(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 set& operator=(initializer_list __il) { clear(); @@ -1195,12 +1191,10 @@ public: insert(__f, __l); } -# if _LIBCPP_STD_VER >= 14 template - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX26 multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : multiset(__f, __l, key_compare(), __a) {} -# endif template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 @@ -1253,11 +1247,9 @@ public: insert(__il.begin(), __il.end()); } -# if _LIBCPP_STD_VER >= 14 - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX26 multiset(initializer_list __il, const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + multiset(initializer_list __il, const allocator_type& __a) : multiset(__il, key_compare(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 multiset& operator=(initializer_list __il) { clear(); diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map index 8cefba01fb5f6..b8b160cd892d4 100644 --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -77,16 +77,16 @@ public: const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_map(size_type n, const allocator_type& a) - : unordered_map(n, hasher(), key_equal(), a) {} // C++14 + : unordered_map(n, hasher(), key_equal(), a) {} unordered_map(size_type n, const hasher& hf, const allocator_type& a) - : unordered_map(n, hf, key_equal(), a) {} // C++14 + : unordered_map(n, hf, key_equal(), a) {} template unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a) - : unordered_map(f, l, n, hasher(), key_equal(), a) {} // C++14 + : unordered_map(f, l, n, hasher(), key_equal(), a) {} template unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) - : unordered_map(f, l, n, hf, key_equal(), a) {} // C++14 + : unordered_map(f, l, n, hf, key_equal(), a) {} template R> unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_map(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } // C++23 @@ -94,10 +94,10 @@ public: unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(from_range, std::forward(rg), n, hf, key_equal(), a) { } // C++23 unordered_map(initializer_list il, size_type n, const allocator_type& a) - : unordered_map(il, n, hasher(), key_equal(), a) {} // C++14 + : unordered_map(il, n, hasher(), key_equal(), a) {} unordered_map(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) - : unordered_map(il, n, hf, key_equal(), a) {} // C++14 + : unordered_map(il, n, hf, key_equal(), a) {} ~unordered_map(); unordered_map& operator=(const unordered_map&); unordered_map& operator=(unordered_map&&) @@ -363,16 +363,16 @@ public: const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_multimap(size_type n, const allocator_type& a) - : unordered_multimap(n, hasher(), key_equal(), a) {} // C++14 + : unordered_multimap(n, hasher(), key_equal(), a) {} unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) - : unordered_multimap(n, hf, key_equal(), a) {} // C++14 + : unordered_multimap(n, hf, key_equal(), a) {} template unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) - : unordered_multimap(f, l, n, hasher(), key_equal(), a) {} // C++14 + : unordered_multimap(f, l, n, hasher(), key_equal(), a) {} template unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) - : unordered_multimap(f, l, n, hf, key_equal(), a) {} // C++14 + : unordered_multimap(f, l, n, hf, key_equal(), a) {} template R> unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_multimap(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } // C++23 @@ -380,10 +380,10 @@ public: unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(from_range, std::forward(rg), n, hf, key_equal(), a) { } // C++23 unordered_multimap(initializer_list il, size_type n, const allocator_type& a) - : unordered_multimap(il, n, hasher(), key_equal(), a) {} // C++14 + : unordered_multimap(il, n, hasher(), key_equal(), a) {} unordered_multimap(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) - : unordered_multimap(il, n, hf, key_equal(), a) {} // C++14 + : unordered_multimap(il, n, hf, key_equal(), a) {} ~unordered_multimap(); unordered_multimap& operator=(const unordered_multimap&); unordered_multimap& operator=(unordered_multimap&&) @@ -993,7 +993,6 @@ public: const key_equal& __eql, const allocator_type& __a); # endif // _LIBCPP_CXX03_LANG -# if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const allocator_type& __a) : unordered_map(__n, hasher(), key_equal(), __a) {} _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a) @@ -1007,7 +1006,7 @@ public: _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {} -# if _LIBCPP_STD_VER >= 23 +# if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> _LIBCPP_HIDE_FROM_ABI unordered_map(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) : unordered_map(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} @@ -1016,8 +1015,9 @@ public: _LIBCPP_HIDE_FROM_ABI unordered_map(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} -# endif +# endif +# ifndef _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_map(__il, __n, hasher(), key_equal(), __a) {} _LIBCPP_HIDE_FROM_ABI @@ -1787,7 +1787,6 @@ public: const key_equal& __eql, const allocator_type& __a); # endif // _LIBCPP_CXX03_LANG -# if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const allocator_type& __a) : unordered_multimap(__n, hasher(), key_equal(), __a) {} _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a) @@ -1801,7 +1800,7 @@ public: _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {} -# if _LIBCPP_STD_VER >= 23 +# if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> _LIBCPP_HIDE_FROM_ABI unordered_multimap(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) : unordered_multimap(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} @@ -1810,8 +1809,9 @@ public: _LIBCPP_HIDE_FROM_ABI unordered_multimap(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} -# endif +# endif +# ifndef _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {} _LIBCPP_HIDE_FROM_ABI diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set index d54d59403b038..10f8b730b842b 100644 --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -76,22 +76,22 @@ public: unordered_set(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - unordered_set(size_type n, const allocator_type& a); // C++14 - unordered_set(size_type n, const hasher& hf, const allocator_type& a); // C++14 + unordered_set(size_type n, const allocator_type& a); + unordered_set(size_type n, const hasher& hf, const allocator_type& a); template - unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14 + unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); template unordered_set(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const allocator_type& a); // C++14 + const hasher& hf, const allocator_type& a); template R> unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_set(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } // C++23 template R> unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_set(from_range, std::forward(rg), n, hf, key_equal(), a) { } // C++23 - unordered_set(initializer_list il, size_type n, const allocator_type& a); // C++14 + unordered_set(initializer_list il, size_type n, const allocator_type& a); unordered_set(initializer_list il, size_type n, - const hasher& hf, const allocator_type& a); // C++14 + const hasher& hf, const allocator_type& a); ~unordered_set(); unordered_set& operator=(const unordered_set&); unordered_set& operator=(unordered_set&&) @@ -324,22 +324,22 @@ public: unordered_multiset(initializer_list, size_type n = /see below/, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - unordered_multiset(size_type n, const allocator_type& a); // C++14 - unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); // C++14 + unordered_multiset(size_type n, const allocator_type& a); + unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); template - unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14 + unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); template unordered_multiset(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const allocator_type& a); // C++14 + const hasher& hf, const allocator_type& a); template R> unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_multiset(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } // C++23 template R> unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(from_range, std::forward(rg), n, hf, key_equal(), a) { } // C++23 - unordered_multiset(initializer_list il, size_type n, const allocator_type& a); // C++14 + unordered_multiset(initializer_list il, size_type n, const allocator_type& a); unordered_multiset(initializer_list il, size_type n, - const hasher& hf, const allocator_type& a); // C++14 + const hasher& hf, const allocator_type& a); ~unordered_multiset(); unordered_multiset& operator=(const unordered_multiset&); unordered_multiset& operator=(unordered_multiset&&) @@ -634,12 +634,10 @@ public: _LIBCPP_HIDE_FROM_ABI unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) {} explicit _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); -# if _LIBCPP_STD_VER >= 14 inline _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const allocator_type& __a) : unordered_set(__n, hasher(), key_equal(), __a) {} inline _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__n, __hf, key_equal(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); template @@ -677,7 +675,6 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template inline _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) @@ -686,7 +683,6 @@ public: _LIBCPP_HIDE_FROM_ABI unordered_set( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -717,14 +713,12 @@ public: const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -# if _LIBCPP_STD_VER >= 14 inline _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_set(__il, __n, hasher(), key_equal(), __a) {} inline _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list __il, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__il, __n, __hf, key_equal(), __a) {} -# endif # endif // _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI ~unordered_set() { static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); @@ -1250,12 +1244,10 @@ public: unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -# if _LIBCPP_STD_VER >= 14 inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const allocator_type& __a) : unordered_multiset(__n, hasher(), key_equal(), __a) {} inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__n, __hf, key_equal(), __a) {} -# endif template _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last); template @@ -1291,7 +1283,6 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) @@ -1300,7 +1291,6 @@ public: inline _LIBCPP_HIDE_FROM_ABI unordered_multiset( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -1331,14 +1321,12 @@ public: const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -# if _LIBCPP_STD_VER >= 14 inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {} inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list __il, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__il, __n, __hf, key_equal(), __a) {} -# endif # endif // _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI ~unordered_multiset() { static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); diff --git a/libcxx/include/vector b/libcxx/include/vector index f289013a682bc..b136cca1f6050 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -39,7 +39,7 @@ public: noexcept(is_nothrow_default_constructible::value); explicit vector(const allocator_type&); explicit vector(size_type n); - explicit vector(size_type n, const allocator_type&); // C++14 + explicit vector(size_type n, const allocator_type&); vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); template vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); @@ -171,7 +171,7 @@ public: vector() noexcept(is_nothrow_default_constructible::value); explicit vector(const allocator_type&) noexcept; - explicit vector(size_type n, const allocator_type& a = allocator_type()); // C++14 + explicit vector(size_type n, const allocator_type& a = allocator_type()); vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); template vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); diff --git a/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp index 014f9c5960e5b..ce2b2ef185d90 100644 --- a/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp @@ -72,7 +72,6 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(*std::next(m.begin()) == V(2, 1)); assert(*std::next(m.begin(), 2) == V(3, 1)); } -# if TEST_STD_VER > 11 { typedef std::pair V; V ar[] = { @@ -113,7 +112,6 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(m.get_allocator() == a); } } -# endif #endif return true; } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp index fb3f4b831cc0d..08320024cc5bd 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp @@ -115,6 +115,46 @@ bool test() { assert(*std::next(m.begin(), 7) == V(3, 1.5)); assert(*std::next(m.begin(), 8) == V(3, 2)); } + { + typedef std::pair V; + V ar[] = { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2), + }; + { + typedef min_allocator A; + typedef test_less C; + A a; + std::multimap m(ar, ar + sizeof(ar) / sizeof(ar[0]), a); + + assert(m.size() == 9); + assert(std::distance(m.begin(), m.end()) == 9); + assert(*m.begin() == V(1, 1)); + assert(*std::next(m.begin(), 3) == V(2, 1)); + assert(*std::next(m.begin(), 6) == V(3, 1)); + assert(m.get_allocator() == a); + } + { + typedef explicit_allocator A; + typedef test_less C; + A a; + std::multimap m(ar, ar + sizeof(ar) / sizeof(ar[0]), a); + + assert(m.size() == 9); + assert(std::distance(m.begin(), m.end()) == 9); + assert(*m.begin() == V(1, 1)); + assert(*std::next(m.begin(), 3) == V(2, 1)); + assert(*std::next(m.begin(), 6) == V(3, 1)); + assert(m.get_allocator() == a); + } + } #endif return true; diff --git a/libcxx/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp b/libcxx/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp index 22ac9bd799e45..ffb655fa8ade5 100644 --- a/libcxx/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp +++ b/libcxx/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp @@ -48,7 +48,7 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(*std::next(m.begin(), 7) == 3); assert(*std::next(m.begin(), 8) == 3); } -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; diff --git a/libcxx/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp b/libcxx/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp index 60167a566145a..c15e05bcc309e 100644 --- a/libcxx/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp +++ b/libcxx/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp @@ -46,7 +46,7 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(*std::next(m.begin()) == 2); assert(*std::next(m.begin(), 2) == 3); } -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/size.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/size.pass.cpp index f8f42bd668f83..c31caa6c2d414 100644 --- a/libcxx/test/std/containers/sequences/deque/deque.cons/size.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/deque.cons/size.pass.cpp @@ -9,6 +9,7 @@ // // explicit deque(size_type n); +// explicit deque(size_type n, const Allocator& a); #include "asan_testing.h" #include @@ -22,7 +23,7 @@ template void test2(unsigned n) { -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 typedef std::deque C; typedef typename C::const_iterator const_iterator; assert(DefaultOnly::count == 0); @@ -62,7 +63,7 @@ void test1(unsigned n) { template void test3(unsigned n, Allocator const& alloc = Allocator()) { -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 typedef std::deque C; { C d(n, alloc); @@ -102,7 +103,7 @@ int main(int, char**) { test >(4095); #endif -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 test3>(1023); test3>(1); test3>(3); diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp index 206854560c19f..89baa06dec475 100644 --- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // // explicit forward_list(size_type n); // constexpr since C++26 @@ -21,15 +23,10 @@ template void check_allocator(unsigned n, Allocator const& alloc = Allocator()) { -#if TEST_STD_VER > 11 typedef std::forward_list C; C d(n, alloc); assert(d.get_allocator() == alloc); assert(static_cast(std::distance(d.begin(), d.end())) == n); -#else - ((void)n); - ((void)alloc); -#endif } int main(int, char**) { @@ -46,14 +43,24 @@ int main(int, char**) { unsigned n = 0; for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n) { -#if TEST_STD_VER >= 11 assert(*i == T()); -#else - ((void)0); -#endif } assert(n == N); } + { + typedef DefaultOnly T; + typedef std::forward_list > C; + unsigned N = 10; + C c(N, std::allocator()); + unsigned n = 0; + + for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n) { + assert(*i == T()); + } + assert(n == N); + check_allocator >(0); + check_allocator >(3); + } #if TEST_STD_VER >= 11 { typedef DefaultOnly T; diff --git a/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp index 55371e8354a9e..4992400c406d7 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp @@ -6,9 +6,12 @@ // //===----------------------------------------------------------------------===// +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // -// explicit list(size_type n); // constexpr since C++26 +// explicit list(size_type n); // constexpr since C++26 +// explicit list(size_type n, const Allocator& a); // constexpr since C++26 #include #include @@ -21,7 +24,6 @@ template TEST_CONSTEXPR_CXX26 void test1(unsigned n, Allocator const& alloc = Allocator()) { -#if TEST_STD_VER > 11 typedef std::list C; { C d(n, alloc); @@ -29,10 +31,6 @@ TEST_CONSTEXPR_CXX26 void test1(unsigned n, Allocator const& alloc = Allocator() assert(static_cast(std::distance(d.begin(), d.end())) == n); assert(d.get_allocator() == alloc); } -#else - ((void)n); - ((void)alloc); -#endif } TEST_CONSTEXPR_CXX26 bool test() { @@ -59,7 +57,19 @@ TEST_CONSTEXPR_CXX26 bool test() { ++i; assert(*i == 0); } -#if TEST_STD_VER > 11 + { + std::list > l(3, std::allocator()); + assert(l.size() == 3); + assert(std::distance(l.begin(), l.end()) == 3); + std::list >::const_iterator i = l.begin(); + assert(*i == 0); + ++i; + assert(*i == 0); + ++i; + assert(*i == 0); + test1 >(3); + } +#if TEST_STD_VER >= 11 { typedef std::list > C; C l(3, min_allocator()); diff --git a/libcxx/test/std/containers/sequences/vector.bool/construct_size.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/construct_size.pass.cpp index 80b3fe307c93a..f97396d67ae9d 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/construct_size.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/construct_size.pass.cpp @@ -10,6 +10,7 @@ // vector // explicit vector(size_type n); +// explicit vector(size_type n, const Allocator& alloc = Allocator()); #include #include @@ -21,7 +22,7 @@ template TEST_CONSTEXPR_CXX20 void test2(typename C::size_type n, typename C::allocator_type const& a = typename C::allocator_type()) { -#if TEST_STD_VER >= 14 +#if TEST_STD_VER >= 11 C c(n, a); LIBCPP_ASSERT(c.__invariants()); assert(c.size() == n); diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp index cbae3653d995f..0902a4070b7aa 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp @@ -38,7 +38,7 @@ test(typename C::size_type n, typename C::allocator_type const& a = typename C:: } // Test with a custom allocator -#if TEST_STD_VER >= 14 +#if TEST_STD_VER >= 11 { C c(n, a); LIBCPP_ASSERT(c.__invariants()); diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_allocator.pass.cpp index e29ecea327971..3fd4e7fcfa5f5 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_allocator.pass.cpp index c2adf98c7eaca..31d4ce0adf437 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_allocator.pass.cpp index 1039e1d92be79..bf1536dd0b44a 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_hash_allocator.pass.cpp index b6e06df9c8fe2..a5f9ddeb0d825 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_allocator.pass.cpp index 450fb7b5e40d4..8e4d7ff8e1fbe 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_allocator.pass.cpp index a9f73f3f45fe2..19bbb305fe10f 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_allocator.pass.cpp index 7ec2dd2efb895..a8371367f7ead 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_allocator.pass.cpp index eab5d60fbf6f4..ec566bb75a2f9 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_allocator.pass.cpp index ad6ad9d1ad1ef..5e694b5d5ed3a 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_hash_allocator.pass.cpp index ee35b36cf7519..7592b10b792ec 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_allocator.pass.cpp index d49be5518922a..70798e3920a7d 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_allocator.pass.cpp index f26fae2a2a81d..42d75cfa28ba0 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_allocator.pass.cpp index bb0cc2441bfb7..314e60381dfcc 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_allocator.pass.cpp index 24b802f4fcca2..f962ddd8f0344 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_allocator.pass.cpp index 994ec058fae94..6eb48201d116c 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_hash_allocator.pass.cpp index 138af889d5978..44e572e10071f 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_allocator.pass.cpp index e536644470122..ddf0a4d02b932 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_allocator.pass.cpp index 6ea22dab1aac9..531215e0671e3 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_allocator.pass.cpp index 7346a951b1976..90c6d9720e90c 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_allocator.pass.cpp index 704fff0f51cca..306ec62c81d7b 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_allocator.pass.cpp index 414485466d71e..bdd2d841283a6 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_hash_allocator.pass.cpp index ba986eba5f71c..48d64a8860e23 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_allocator.pass.cpp index 99abd12745eca..6af94925a5a2b 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_allocator.pass.cpp index e44854eb0a132..11c3e7bd2ee0c 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index ed6d42fd4c05e..11c3dca1a358a 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -106,13 +106,17 @@ class AArch64 : public TargetInfo { struct AArch64Relaxer { Ctx &ctx; - bool safeToRelaxAdrpLdr = false; + SmallPtrSet unsafeToRelaxAdrpLdr; - AArch64Relaxer(Ctx &ctx, ArrayRef relocs); + AArch64Relaxer(Ctx &ctx, ArrayRef relocs, uint64_t secAddr, + uint8_t *buf); bool tryRelaxAdrpAdd(const Relocation &adrpRel, const Relocation &addRel, uint64_t secAddr, uint8_t *buf) const; bool tryRelaxAdrpLdr(const Relocation &adrpRel, const Relocation &ldrRel, uint64_t secAddr, uint8_t *buf) const; + bool isLegalAdrpLdrRelaxationCandidate(const Relocation &adrpRel, + const Relocation &ldrRel, + uint64_t secAddr, uint8_t *buf) const; }; } // namespace @@ -896,26 +900,30 @@ void AArch64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, llvm_unreachable("invalid relocation for TLS IE to LE relaxation"); } -AArch64Relaxer::AArch64Relaxer(Ctx &ctx, ArrayRef relocs) +AArch64Relaxer::AArch64Relaxer(Ctx &ctx, ArrayRef relocs, + uint64_t secAddr, uint8_t *buf) : ctx(ctx) { if (!ctx.arg.relax) return; - // Check if R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC - // always appear in pairs. + // For a given symbol R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC + // relaxation is all-or-nothing. We can't relax only some of them, as there + // may be a jump destination between the two relocations. size_t i = 0; const size_t size = relocs.size(); for (; i != size; ++i) { if (relocs[i].type == R_AARCH64_ADR_GOT_PAGE) { - if (i + 1 < size && relocs[i + 1].type == R_AARCH64_LD64_GOT_LO12_NC) { + if (i + 1 < size && relocs[i + 1].type == R_AARCH64_LD64_GOT_LO12_NC && + !unsafeToRelaxAdrpLdr.contains(relocs[i].sym) && + isLegalAdrpLdrRelaxationCandidate(relocs[i], relocs[i + 1], secAddr, + buf)) { ++i; continue; } - break; + unsafeToRelaxAdrpLdr.insert(relocs[i].sym); } else if (relocs[i].type == R_AARCH64_LD64_GOT_LO12_NC) { - break; + unsafeToRelaxAdrpLdr.insert(relocs[i].sym); } } - safeToRelaxAdrpLdr = i == size; } bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel, @@ -966,23 +974,9 @@ bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel, return true; } -bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, - const Relocation &ldrRel, uint64_t secAddr, - uint8_t *buf) const { - if (!safeToRelaxAdrpLdr) - return false; - - // When the definition of sym is not preemptible then we may - // be able to relax - // ADRP xn, :got: sym - // LDR xn, [ xn :got_lo12: sym] - // to - // ADRP xn, sym - // ADD xn, xn, :lo_12: sym - - if (adrpRel.type != R_AARCH64_ADR_GOT_PAGE || - ldrRel.type != R_AARCH64_LD64_GOT_LO12_NC) - return false; +bool AArch64Relaxer::isLegalAdrpLdrRelaxationCandidate( + const Relocation &adrpRel, const Relocation &ldrRel, uint64_t secAddr, + uint8_t *buf) const { // Check if the relocations apply to consecutive instructions. if (adrpRel.offset + 4 != ldrRel.offset) return false; @@ -1022,10 +1016,37 @@ bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, if (val != llvm::SignExtend64(val, 33)) return false; + return true; +} + +bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, + const Relocation &ldrRel, uint64_t secAddr, + uint8_t *buf) const { + // When the definition of sym is not preemptible then we may + // be able to relax + // ADRP xn, :got: sym + // LDR xn, [ xn :got_lo12: sym] + // to + // ADRP xn, sym + // ADD xn, xn, :lo_12: sym + + if (!ctx.arg.relax || adrpRel.type != R_AARCH64_ADR_GOT_PAGE || + ldrRel.type != R_AARCH64_LD64_GOT_LO12_NC) + return false; + + Symbol *sym = adrpRel.sym; + if (unsafeToRelaxAdrpLdr.contains(sym)) + return false; + + assert(isLegalAdrpLdrRelaxationCandidate(adrpRel, ldrRel, secAddr, buf) && + "Should have been marked as unsafe"); + + uint32_t adrpInstr = read32le(buf + adrpRel.offset); + uint32_t adrpDestReg = adrpInstr & 0x1f; Relocation adrpSymRel = {RE_AARCH64_PAGE_PC, R_AARCH64_ADR_PREL_PG_HI21, - adrpRel.offset, /*addend=*/0, &sym}; + adrpRel.offset, /*addend=*/0, sym}; Relocation addRel = {R_ABS, R_AARCH64_ADD_ABS_LO12_NC, ldrRel.offset, - /*addend=*/0, &sym}; + /*addend=*/0, sym}; // adrp x_ write32le(buf + adrpSymRel.offset, 0x90000000 | adrpDestReg); @@ -1034,11 +1055,11 @@ bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, ctx.target->relocate( buf + adrpSymRel.offset, adrpSymRel, - SignExtend64(getAArch64Page(sym.getVA(ctx)) - + SignExtend64(getAArch64Page(sym->getVA(ctx)) - getAArch64Page(secAddr + adrpSymRel.offset), 64)); ctx.target->relocate(buf + addRel.offset, addRel, - SignExtend64(sym.getVA(ctx), 64)); + SignExtend64(sym->getVA(ctx), 64)); tryRelaxAdrpAdd(adrpSymRel, addRel, secAddr, buf); return true; } @@ -1052,7 +1073,7 @@ static bool needsGotForMemtag(const Relocation &rel) { void AArch64::relocateAlloc(InputSection &sec, uint8_t *buf) const { uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff; const ArrayRef relocs = sec.relocs(); - AArch64Relaxer relaxer(ctx, relocs); + AArch64Relaxer relaxer(ctx, relocs, secAddr, buf); for (size_t i = 0, size = relocs.size(); i != size; ++i) { const Relocation &rel = relocs[i]; if (rel.expr == R_NONE) // See finalizeAddressDependentContent() diff --git a/lld/test/ELF/aarch64-adrp-ldr-got.s b/lld/test/ELF/aarch64-adrp-ldr-got.s index 56a90aac3876c..a8216da9f20c3 100644 --- a/lld/test/ELF/aarch64-adrp-ldr-got.s +++ b/lld/test/ELF/aarch64-adrp-ldr-got.s @@ -4,6 +4,7 @@ # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/a.s -o %t/a.o # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/unpaired.s -o %t/unpaired.o # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/lone-ldr.s -o %t/lone-ldr.o +# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/all-or-nothing.s -o %t/all-or-nothing.o # RUN: ld.lld %t/a.o -T %t/out-of-adr-range.t -o %t/a # RUN: llvm-objdump --no-show-raw-insn -d %t/a | FileCheck %s @@ -49,7 +50,8 @@ # RUN: llvm-objdump --no-show-raw-insn -d %t/out-of-range | \ # RUN: FileCheck --check-prefix=X1-NO-RELAX %s -## Relocations do not appear in pairs, no relaxations should be applied. +## Relocations do not appear in pairs, no relaxations should be applied for +## that symbol. We can still relax other symbols. # RUN: ld.lld %t/unpaired.o -o %t/unpaired # RUN: llvm-objdump --no-show-raw-insn -d %t/unpaired | \ # RUN: FileCheck --check-prefix=UNPAIRED %s @@ -58,6 +60,9 @@ # UNPAIRED-NEXT: b # UNPAIRED-NEXT: adrp x0 # UNPAIRED: ldr x0 +## This is a different symbol. +# UNPAIRED: nop +# UNPAIRED: adr x1 ## Relocations do not appear in pairs, no relaxations should be applied. # RUN: ld.lld %t/lone-ldr.o -o %t/lone-ldr @@ -66,6 +71,26 @@ # LONE-LDR: ldr x0 +## Make sure that relaxation is not applied if not all adrp+ldr pairs for +## a given symbol can be relaxed. This is not legal, because there may be +## a branch destination between the adrp and ldr instructions. We can still +## perform the relaxation for other symbols, or the same symbol in a different +## section. +# RUN: ld.lld %t/all-or-nothing.o -o %t/all-or-nothing +# RUN: llvm-objdump --no-show-raw-insn -d %t/all-or-nothing | \ +# RUN: FileCheck --check-prefix=ALL-OR-NOTHING %s + +# ALL-OR-NOTHING-LABEL: <_start>: +# ALL-OR-NOTHING: adrp x1 +# ALL-OR-NOTHING: ldr x1 +# ALL-OR-NOTHING: adrp x1 +# ALL-OR-NOTHING: ldr x2 +# ALL-OR-NOTHING: nop +# ALL-OR-NOTHING: adr x1 +# ALL-OR-NOTHING-LABEL: : +# ALL-OR-NOTHING: nop +# ALL-OR-NOTHING: adr x1 + ## This linker script ensures that .rodata and .text are sufficiently (>1M) ## far apart so that the adrp + ldr pair cannot be relaxed to adr + nop. #--- out-of-adr-range.t @@ -95,25 +120,40 @@ SECTIONS { .hidden x x: .word 10 +.hidden y +y: +.word 10 +.hidden z +z: +.word 10 +.hidden u +u: +.word 10 +.hidden v +v: +.word 10 .text .global _start _start: adrp x1, :got:x ldr x1, [x1, #:got_lo12:x] - adrp x2, :got:x+1 - ldr x2, [x2, #:got_lo12:x] - adrp x3, :got:x - ldr x3, [x3, #:got_lo12:x+8] - adrp x4, :got:x - ldr x5, [x4, #:got_lo12:x] - adrp x6, :got:x - ldr x6, [x0, #:got_lo12:x] + adrp x2, :got:y+1 + ldr x2, [x2, #:got_lo12:y] + adrp x3, :got:z + ldr x3, [x3, #:got_lo12:z+8] + adrp x4, :got:u + ldr x5, [x4, #:got_lo12:u] + adrp x6, :got:v + ldr x6, [x0, #:got_lo12:v] #--- unpaired.s .text .hidden x x: nop +.hidden y +y: + nop .global _start _start: adrp x0, :got:x @@ -121,6 +161,8 @@ _start: adrp x0, :got:x L: ldr x0, [x0, #:got_lo12:x] + adrp x1, :got:y + ldr x1, [x1, #:got_lo12:y] #--- lone-ldr.s .text @@ -130,3 +172,27 @@ x: .global _start _start: ldr x0, [x0, #:got_lo12:x] + +#--- all-or-nothing.s +.rodata +.hidden x +x: +.word 10 +.hidden y +y: +.word 10 +.text +.global _start +_start: + adrp x1, :got:x + ldr x1, [x1, #:got_lo12:x] + adrp x1, :got:x + ldr x2, [x1, #:got_lo12:x] + adrp x1, :got:y + ldr x1, [x1, #:got_lo12:y] + +.section .text.foo +.global foo +foo: + adrp x1, :got:x + ldr x1, [x1, #:got_lo12:x] diff --git a/lldb/bindings/interface/SBValueDocstrings.i b/lldb/bindings/interface/SBValueDocstrings.i index bedb553e94c3a..e24c3df5c0bf4 100644 --- a/lldb/bindings/interface/SBValueDocstrings.i +++ b/lldb/bindings/interface/SBValueDocstrings.i @@ -213,7 +213,7 @@ linked list." or SetData(). Returns False when the value is not writable. An example would be a - variable values reconstructed from debug info via a computation or a constant. + variable value reconstructed from debug info via a computation or a constant. A True result does not guarantee a write will succeed; other runtime conditions may still prevent a successful write." ) lldb::SBValue::CanSetValue; diff --git a/lldb/include/lldb/DataFormatters/TypeCategory.h b/lldb/include/lldb/DataFormatters/TypeCategory.h index 884a27d76e055..9011b43d44489 100644 --- a/lldb/include/lldb/DataFormatters/TypeCategory.h +++ b/lldb/include/lldb/DataFormatters/TypeCategory.h @@ -347,10 +347,7 @@ class TypeCategoryImpl { std::string GetDescription(); bool AnyMatches(const FormattersMatchCandidate &candidate_type, - FormatCategoryItems items = ALL_ITEM_TYPES, - bool only_enabled = true, - const char **matching_category = nullptr, - FormatCategoryItems *matching_type = nullptr); + FormatCategoryItems items = ALL_ITEM_TYPES); void AutoComplete(CompletionRequest &request, FormatCategoryItems items); diff --git a/lldb/include/lldb/Host/JSONTransport.h b/lldb/include/lldb/Host/JSONTransport.h index c3a90cb0c3364..0f58697e9f34d 100644 --- a/lldb/include/lldb/Host/JSONTransport.h +++ b/lldb/include/lldb/Host/JSONTransport.h @@ -514,6 +514,14 @@ class Binder : public JSONTransport::MessageHandler { template void Bind(llvm::StringLiteral method, Fn &&fn, Args &&...args); + /// Bind an asynchronous handler for an incoming request. The handler receives + /// a Reply to invoke later instead of returning a result. This lets it defer + /// the response, e.g. until a request it forwarded elsewhere is answered. + /// Handler should be e.g. `void peek(const PeekParams&, Reply);` + /// PeekParams must be JSON parsable and PeekResult must be serializable. + template + void BindAsync(llvm::StringLiteral method, Fn &&fn, Args &&...args); + /// Bind a handler for an incoming event. /// e.g. `bind("peek", &ThisModule::peek, this);` /// Handler should be e.g. `void peek(const PeekParams&);` @@ -869,6 +877,52 @@ llvm::Expected Binder::Parse(const llvm::json::Value &raw, return std::move(result); } +#if __cplusplus >= 202002L +template +#else +template +#endif +template +void Binder::BindAsync(llvm::StringLiteral method, Fn &&fn, + Args &&...args) { + assert(m_request_handlers.find(method) == m_request_handlers.end() && + "request already bound"); + // The handler is captured by value and may be invoked once per incoming + // request, so it is invoked as an lvalue (never forwarded) to avoid moving + // from it between calls. + if constexpr (std::is_void_v) { + m_request_handlers[method] = + [fn, args...](const Req &req, + Callback reply) mutable { + Reply typed_reply = + [req, reply = std::move(reply)]( + llvm::Expected result) mutable { + if (!result) + return reply(Proto::Make(req, result.takeError())); + reply(Proto::Make(req, toJSON(*result))); + }; + std::invoke(fn, args..., std::move(typed_reply)); + }; + } else { + m_request_handlers[method] = + [method, fn, args...](const Req &req, + Callback reply) mutable { + Reply typed_reply = + [req, reply = std::move(reply)]( + llvm::Expected result) mutable { + if (!result) + return reply(Proto::Make(req, result.takeError())); + reply(Proto::Make(req, toJSON(*result))); + }; + llvm::Expected params = + Parse(Proto::Extract(req), method); + if (!params) + return typed_reply(params.takeError()); + std::invoke(fn, args..., *params, std::move(typed_reply)); + }; + } +} + } // namespace lldb_private::transport #endif diff --git a/lldb/include/lldb/Protocol/MCP/Client.h b/lldb/include/lldb/Protocol/MCP/Client.h new file mode 100644 index 0000000000000..cefbd136cda2a --- /dev/null +++ b/lldb/include/lldb/Protocol/MCP/Client.h @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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 LLDB_PROTOCOL_MCP_CLIENT_H +#define LLDB_PROTOCOL_MCP_CLIENT_H + +#include "lldb/Protocol/MCP/Protocol.h" +#include "lldb/Protocol/MCP/Transport.h" +#include "llvm/ADT/FunctionExtras.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace lldb_protocol::mcp { + +/// An MCP client: the counterpart to Server. It speaks the MCP protocol to a +/// remote server over a transport and exposes the protocol's requests as typed, +/// asynchronous calls. Each request completes by invoking its Reply on the +/// transport's MainLoop. +class Client { +public: + template using Reply = lldb_private::transport::Reply; + + Client(std::unique_ptr transport, + LogCallback log_callback = {}); + ~Client() = default; + + Client(const Client &) = delete; + Client &operator=(const Client &) = delete; + + /// Registers the client with the transport's MainLoop. Must be called before + /// issuing any request. + llvm::Error Run(); + + /// Sets a handler invoked when the transport disconnects (EOF). + void SetDisconnectHandler(llvm::unique_function handler); + /// Sets a handler invoked on a transport-level error. + void SetErrorHandler(llvm::unique_function handler); + + /// Outgoing MCP requests to the server. Each sends its request and invokes + /// its Reply asynchronously when the response arrives. + /// @{ + void Initialize(const InitializeParams ¶ms, + Reply reply); + void ToolsList(Reply reply); + void ToolsCall(const CallToolParams ¶ms, Reply reply); + void ResourcesList(Reply reply); + void ResourcesRead(const ReadResourceParams ¶ms, + Reply reply); + /// @} + + /// MCP notifications. + void NotifyInitialized(); + +private: + void Log(llvm::StringRef message); + + /// Trampolines registered with the binder, which forward to the move-only + /// handlers below. The binder requires copyable callables, so the handlers + /// cannot be registered with it directly. + /// @{ + void HandleDisconnect(); + void HandleError(llvm::Error error); + /// @} + + std::unique_ptr m_transport; + MCPBinderUP m_binder; + LogCallback m_log_callback; + + llvm::unique_function m_disconnect_handler; + llvm::unique_function m_error_handler; + + lldb_private::transport::OutgoingRequest + m_initialize; + lldb_private::transport::OutgoingRequest m_tools_list; + lldb_private::transport::OutgoingRequest + m_tools_call; + lldb_private::transport::OutgoingRequest + m_resources_list; + lldb_private::transport::OutgoingRequest + m_resources_read; + lldb_private::transport::OutgoingEvent m_notify_initialized; +}; + +} // namespace lldb_protocol::mcp + +#endif diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py index 2b2412bcea072..ac74770e2e4bc 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py @@ -153,6 +153,13 @@ def create_debug_adapter( def cleanup_adapter(): if adapter.is_alive: adapter.kill() + # The debug adapter may have a reason the test failed. + if stderr := adapter.process.stderr: + if err_str := stderr.read().decode(): + self.logger.debug("The adapter stderr: \n%s", err_str) + if stdout := adapter.process.stdout: + if err_str := stdout.read().decode(): + self.logger.debug("The adapter stdout: \n%s", err_str) self.addTearDownHook(cleanup_adapter) return adapter diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/utils.py b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/utils.py index db89d9f77ceba..61147e3e31e52 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/utils.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/utils.py @@ -156,6 +156,7 @@ def kill(self): self._process.wait(timeout=2.0) except subprocess.TimeoutExpired: self._process.kill() + self._process.wait() def _read_listening_uri(self) -> str: # lldb-dap will print the listening address once the listener is diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index d86aca0e71854..c1dc949a7b815 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -2259,8 +2259,7 @@ bool CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, // name-based lookup here to try to prevent conflicts. FormattersMatchCandidate candidate_type(type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags()); - if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter, - false)) { + if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter)) { if (error) *error = Status::FromErrorStringWithFormatv( "cannot add synthetic for type {0} when " @@ -2401,8 +2400,7 @@ class CommandObjectTypeFilterAdd : public CommandObjectParsed { FormattersMatchCandidate candidate_type( type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags()); lldb::SyntheticChildrenSP entry; - if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth, - false)) { + if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth)) { if (error) *error = Status::FromErrorStringWithFormatv( "cannot add filter for type {0} when " diff --git a/lldb/source/DataFormatters/TypeCategory.cpp b/lldb/source/DataFormatters/TypeCategory.cpp index 4d8663ea9c03e..b1cc0d61b4833 100644 --- a/lldb/source/DataFormatters/TypeCategory.cpp +++ b/lldb/source/DataFormatters/TypeCategory.cpp @@ -185,48 +185,27 @@ uint32_t TypeCategoryImpl::GetCount(FormatCategoryItems items) { } bool TypeCategoryImpl::AnyMatches( - const FormattersMatchCandidate &candidate_type, FormatCategoryItems items, - bool only_enabled, const char **matching_category, - FormatCategoryItems *matching_type) { - if (!IsEnabled() && only_enabled) - return false; - + const FormattersMatchCandidate &candidate_type, FormatCategoryItems items) { if (items & eFormatCategoryItemFormat) { if (m_format_cont.AnyMatches(candidate_type)) { - if (matching_category) - *matching_category = m_name.GetCString(); - if (matching_type) - *matching_type = eFormatCategoryItemFormat; return true; } } if (items & eFormatCategoryItemSummary) { if (m_summary_cont.AnyMatches(candidate_type)) { - if (matching_category) - *matching_category = m_name.GetCString(); - if (matching_type) - *matching_type = eFormatCategoryItemSummary; return true; } } if (items & eFormatCategoryItemFilter) { if (m_filter_cont.AnyMatches(candidate_type)) { - if (matching_category) - *matching_category = m_name.GetCString(); - if (matching_type) - *matching_type = eFormatCategoryItemFilter; return true; } } if (items & eFormatCategoryItemSynth) { if (m_synth_cont.AnyMatches(candidate_type)) { - if (matching_category) - *matching_category = m_name.GetCString(); - if (matching_type) - *matching_type = eFormatCategoryItemSynth; return true; } } diff --git a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp index 72d03e2348e59..8226bb6aea424 100644 --- a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp +++ b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp @@ -88,6 +88,7 @@ uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) { .Cases({"sp", "x31"}, LLDB_REGNUM_GENERIC_SP) .Cases({"fp", "x29"}, LLDB_REGNUM_GENERIC_FP) .Case("cpsr", LLDB_REGNUM_GENERIC_FLAGS) + .Case("tpidr", LLDB_REGNUM_GENERIC_TP) .Case("x0", LLDB_REGNUM_GENERIC_ARG1) .Case("x1", LLDB_REGNUM_GENERIC_ARG2) .Case("x2", LLDB_REGNUM_GENERIC_ARG3) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 0506b7d4da40f..b60f1d9e41958 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -13,6 +13,7 @@ #include "DWARFDebugInfo.h" #include "DWARFDeclContext.h" #include "DWARFDefines.h" +#include "DWARFFormValue.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" @@ -2572,7 +2573,7 @@ struct VariantMember { explicit VariantMember(DWARFDIE &die, ModuleSP module_sp); bool IsDefault() const; - std::optional discr_value; + std::optional discr_value; DWARFFormValue type_ref; ConstString variant_name; uint32_t byte_offset; @@ -2600,8 +2601,34 @@ bool VariantMember::IsDefault() const { return !discr_value; } VariantMember::VariantMember(DWARFDIE &die, lldb::ModuleSP module_sp) { assert(die.Tag() == llvm::dwarf::DW_TAG_variant); - this->discr_value = - die.GetAttributeValueAsOptionalUnsigned(DW_AT_discr_value); + + DWARFFormValue discr_form; + die.GetDIE()->GetAttributeValue(die.GetCU(), DW_AT_discr_value, discr_form); + + // Rust can output 128-bit discriminants (e.g. NonNull) as + // `DW_FORM_block1`. There is a `data16` dwarf form, but DWARFFormValue treats + // it as a BlockData anyway. Handling is included for it just in case rust's + // output changes to the `data16` form. + dw_form_t form = discr_form.Form(); + if ((form == DW_FORM_block1 && discr_form.Unsigned() == 16) || + form == DW_FORM_data16) { + const uint8_t *block_data = discr_form.BlockData(); + + DataExtractor extractor(block_data, 16, die.GetCU()->GetByteOrder(), + die.GetCU()->GetAddressByteSize()); + lldb::offset_t offset = 0; + uint64_t lo = extractor.GetU64(&offset); + uint64_t hi = extractor.GetU64(&offset); + uint64_t words[] = {lo, hi}; + this->discr_value = llvm::APInt(128, words); + } else { + if (auto result = + die.GetAttributeValueAsOptionalUnsigned(DW_AT_discr_value)) { + this->discr_value = llvm::APInt(sizeof(uint64_t) * 8, result.value()); + } else { + this->discr_value = std::nullopt; + }; + } for (auto child_die : die.children()) { switch (child_die.Tag()) { @@ -3838,9 +3865,14 @@ void DWARFASTParserClang::ParseRustVariantPart( m_ast.CompleteTagDeclarationDefinition(field_type); - auto name = has_discriminant - ? llvm::formatv("$variant${0}", member.discr_value.value()) - : std::string("$variant$"); + auto name = std::string("$variant$"); + if (has_discriminant) { + // u128::MAX = 340282366920938463463374607431768211455 which is 39 digits + // long + 1 for null terminator. + llvm::SmallString<40> discr_str; + member.discr_value.value().toStringUnsigned(discr_str); + name.append(discr_str.c_str()); + } auto variant_decl = m_ast.AddFieldToRecordType( inner_holder, llvm::StringRef(name), field_type, 0); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 4b02124e987e8..aea2267277656 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -724,6 +724,9 @@ DWARFUnit::GetDIEBitSizeAndSign(uint64_t relative_die_offset) const { DWARFDIE die = const_cast(this)->GetDIE(abs_die_offset); if (!die) return llvm::createStringError("cannot resolve DW_OP_convert type DIE"); + if (die.Tag() != DW_TAG_base_type) + return llvm::createStringError( + "DW_OP_convert type DIE is not a DW_TAG_base_type"); uint64_t encoding = die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user); uint64_t bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; diff --git a/lldb/source/Protocol/MCP/CMakeLists.txt b/lldb/source/Protocol/MCP/CMakeLists.txt index 5258cb61a7d10..851c54aff8eeb 100644 --- a/lldb/source/Protocol/MCP/CMakeLists.txt +++ b/lldb/source/Protocol/MCP/CMakeLists.txt @@ -1,4 +1,5 @@ add_lldb_library(lldbProtocolMCP NO_PLUGIN_DEPENDENCIES + Client.cpp MCPError.cpp Protocol.cpp Server.cpp diff --git a/lldb/source/Protocol/MCP/Client.cpp b/lldb/source/Protocol/MCP/Client.cpp new file mode 100644 index 0000000000000..edf651920ada2 --- /dev/null +++ b/lldb/source/Protocol/MCP/Client.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Protocol/MCP/Client.h" +#include "lldb/Protocol/MCP/Protocol.h" +#include "lldb/Protocol/MCP/Transport.h" +#include "llvm/Support/FormatVariadic.h" + +using namespace llvm; +using namespace lldb_protocol::mcp; + +Client::Client(std::unique_ptr transport, + LogCallback log_callback) + : m_transport(std::move(transport)), + m_binder(std::make_unique(*m_transport)), + m_log_callback(std::move(log_callback)) { + m_initialize = + m_binder->Bind("initialize"); + m_tools_list = m_binder->Bind("tools/list"); + m_tools_call = m_binder->Bind("tools/call"); + m_resources_list = + m_binder->Bind("resources/list"); + m_resources_read = + m_binder->Bind("resources/read"); + m_notify_initialized = m_binder->Bind("notifications/initialized"); +} + +llvm::Error Client::Run() { + m_binder->OnDisconnect(&Client::HandleDisconnect, this); + m_binder->OnError(&Client::HandleError, this); + return m_transport->RegisterMessageHandler(*m_binder); +} + +void Client::SetDisconnectHandler(llvm::unique_function handler) { + m_disconnect_handler = std::move(handler); +} + +void Client::SetErrorHandler(llvm::unique_function handler) { + m_error_handler = std::move(handler); +} + +void Client::HandleDisconnect() { + if (m_disconnect_handler) + m_disconnect_handler(); +} + +void Client::HandleError(llvm::Error error) { + if (m_error_handler) + m_error_handler(std::move(error)); + else + consumeError(std::move(error)); +} + +void Client::Initialize(const InitializeParams ¶ms, + Reply reply) { + m_initialize(params, std::move(reply)); +} + +void Client::ToolsList(Reply reply) { + m_tools_list(std::move(reply)); +} + +void Client::ToolsCall(const CallToolParams ¶ms, + Reply reply) { + m_tools_call(params, std::move(reply)); +} + +void Client::ResourcesList(Reply reply) { + m_resources_list(std::move(reply)); +} + +void Client::ResourcesRead(const ReadResourceParams ¶ms, + Reply reply) { + m_resources_read(params, std::move(reply)); +} + +void Client::NotifyInitialized() { m_notify_initialized(); } + +void Client::Log(llvm::StringRef message) { + if (m_log_callback) + m_log_callback(message); +} diff --git a/lldb/source/Protocol/MCP/Protocol.cpp b/lldb/source/Protocol/MCP/Protocol.cpp index 0988f456adc26..13069ef28b175 100644 --- a/lldb/source/Protocol/MCP/Protocol.cpp +++ b/lldb/source/Protocol/MCP/Protocol.cpp @@ -340,6 +340,19 @@ bool fromJSON(const json::Value &V, ServerCapabilities &C, json::Path P) { if (O->find("tools") != O->end()) C.supportsToolsList = true; + if (const json::Object *resources = O->getObject("resources")) { + C.supportsResourcesList = + resources->getBoolean("listChanged").value_or(false); + C.supportsResourcesSubscribe = + resources->getBoolean("subscribe").value_or(false); + } + + if (O->find("completions") != O->end()) + C.supportsCompletions = true; + + if (O->find("logging") != O->end()) + C.supportsLogging = true; + return true; } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 4084d72ee1317..daa1b1c43efa8 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2659,8 +2659,10 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, } } - if (replaced_modules.empty()) - m_images.Append(module_sp, notify); + if (replaced_modules.empty()) { + if (!m_images.AppendIfNeeded(module_sp, notify) && notify) + NotifyModuleAdded(m_images, module_sp); + } for (ModuleSP &old_module_sp : replaced_modules) { auto old_module_wp = old_module_sp->weak_from_this(); diff --git a/lldb/test/API/lang/cpp/builtin_types/int/Makefile b/lldb/test/API/lang/cpp/builtin_types/int/Makefile new file mode 100644 index 0000000000000..99998b20bcb05 --- /dev/null +++ b/lldb/test/API/lang/cpp/builtin_types/int/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/builtin_types/int/TestIntTypes.py b/lldb/test/API/lang/cpp/builtin_types/int/TestIntTypes.py new file mode 100644 index 0000000000000..932dd17192163 --- /dev/null +++ b/lldb/test/API/lang/cpp/builtin_types/int/TestIntTypes.py @@ -0,0 +1,43 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCase(TestBase): + def test(self): + """Check the types and values of all integer-typed variables.""" + self.build_and_run() + + self.expect_var_path("the_short", type="short", value="-31987") + self.expect_expr("the_short", result_type="short", result_value="-31987") + + self.expect_var_path("the_unsigned_short", type="unsigned short", value="65000") + self.expect_expr( + "the_unsigned_short", result_type="unsigned short", result_value="65000" + ) + + self.expect_var_path("the_int", type="int", value="-1100110") + self.expect_expr("the_int", result_type="int", result_value="-1100110") + + self.expect_var_path( + "the_unsigned_int", type="unsigned int", value="4000000000" + ) + self.expect_expr( + "the_unsigned_int", result_type="unsigned int", result_value="4000000000" + ) + + # Check edge-case values: smallest, largest, zero and -1. + self.expect_var_path("short_min", type="short", value="-32768") + self.expect_var_path("short_max", type="short", value="32767") + self.expect_var_path("short_zero", type="short", value="0") + self.expect_var_path("short_neg_one", type="short", value="-1") + self.expect_var_path("ushort_zero", type="unsigned short", value="0") + self.expect_var_path("ushort_max", type="unsigned short", value="65535") + + self.expect_var_path("int_min", type="int", value="-2147483648") + self.expect_var_path("int_max", type="int", value="2147483647") + self.expect_var_path("int_zero", type="int", value="0") + self.expect_var_path("int_neg_one", type="int", value="-1") + self.expect_var_path("uint_zero", type="unsigned int", value="0") + self.expect_var_path("uint_max", type="unsigned int", value="4294967295") diff --git a/lldb/test/API/lang/cpp/builtin_types/int/main.cpp b/lldb/test/API/lang/cpp/builtin_types/int/main.cpp new file mode 100644 index 0000000000000..c20d9e24889ba --- /dev/null +++ b/lldb/test/API/lang/cpp/builtin_types/int/main.cpp @@ -0,0 +1,23 @@ +int main() { + short the_short = -31987; + unsigned short the_unsigned_short = 65000; + int the_int = -1100110; + unsigned int the_unsigned_int = 4000000000u; + + // Edge-case values: smallest, largest, zero and -1. + short short_min = -32768; + short short_max = 32767; + short short_zero = 0; + short short_neg_one = -1; + unsigned short ushort_zero = 0; + unsigned short ushort_max = 65535; + + int int_min = -2147483647 - 1; + int int_max = 2147483647; + int int_zero = 0; + int int_neg_one = -1; + unsigned int uint_zero = 0; + unsigned int uint_max = 4294967295u; + + return 0; // break here +} diff --git a/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py b/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py index bf64f7f822ea2..63eb0e70a2f50 100644 --- a/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py +++ b/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py @@ -1,57 +1,56 @@ -import dap_server -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil -import lldbdap_testcase -import re +from lldbsuite.test.decorators import ( + skipIfTargetDoesNotSupportSharedLibraries, + skipIfWindows, +) +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs, StoppedReason +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase @skipIfTargetDoesNotSupportSharedLibraries() -class TestDAP_module_event(lldbdap_testcase.DAPTestCaseBase): +class TestDAP_module_event(DAPTestCaseBase): @skipIfWindows def test_module_event(self): + session = self.build_and_create_session() program = self.getBuildArtifact("a.out") - self.build_and_launch(program) source = "main.cpp" - breakpoint1_line = line_number(source, "// breakpoint 1") - breakpoint2_line = line_number(source, "// breakpoint 2") - breakpoint3_line = line_number(source, "// breakpoint 3") - - breakpoint_ids = self.set_source_breakpoints( - source, [breakpoint1_line, breakpoint2_line, breakpoint3_line] + bp1_line = line_number(source, "// breakpoint 1") + bp2_line = line_number(source, "// breakpoint 2") + bp3_line = line_number(source, "// breakpoint 3") + + with session.configure(LaunchArgs(program=program)) as ctx: + [bp1, bp2, bp3] = session.resolve_source_breakpoints( + source, [bp1_line, bp2_line, bp3_line] + ) + # Wait for the breakpoint before dlopen. + before_dlopen_event = session.verify_stopped_on_breakpoint( + bp1, after=ctx.process_event ) - self.continue_to_breakpoints(breakpoint_ids) - - # We're now stopped at breakpoint 1 before the dlopen. Flush all the module events. - self.dap_server.wait_for_module_events() # Continue to the second breakpoint, before the dlclose. - self.continue_to_breakpoints(breakpoint_ids) + session.continue_to_breakpoint(bp2) # Make sure we got a module event for libother. - event = self.dap_server.wait_for_event(["module"]) - self.assertIsNotNone(event, "didn't get a module event") - module_name = event["body"]["module"]["name"] - module_id = event["body"]["module"]["id"] - self.assertEqual(event["body"]["reason"], "new") - self.assertIn("libother", module_name) + new_module_event = session.verify_next_module_event(after=before_dlopen_event) + module_id = new_module_event.body.module.id + self.assertEqual(new_module_event.body.reason, "new") + self.assertIn("libother", new_module_event.body.module.name) # Continue to the third breakpoint, after the dlclose. - self.continue_to_breakpoints(breakpoint_ids) + session.continue_to_breakpoint(bp3) # Make sure we got a module event for libother. - event = self.dap_server.wait_for_event(["module"]) - self.assertIsNotNone(event, "didn't get a module event") - reason = event["body"]["reason"] + removed_module_event = session.verify_next_module_event(after=new_module_event) + reason = removed_module_event.body.reason self.assertEqual(reason, "removed") - self.assertEqual(event["body"]["module"]["id"], module_id) + self.assertEqual(removed_module_event.body.module.id, module_id) # The removed module event should omit everything but the module id and name # as they are required fields. - module_data = event["body"]["module"] - required_keys = ["id", "name"] - self.assertListEqual(list(module_data.keys()), required_keys) - self.assertEqual(module_data["name"], "", "expects empty name.") + removed_module = removed_module_event.body.module + self.assertIsNotNone(removed_module.id) + self.assertIsNotNone(removed_module.name) + self.assertEqual(removed_module.name, "", "expects empty name.") - self.continue_to_exit() + session.continue_to_exit() diff --git a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py index 629427a4e138d..ce7a2b8dc8b1f 100644 --- a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py +++ b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py @@ -2,88 +2,95 @@ Test lldb-dap module request """ -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -import lldbdap_testcase +import platform import re +from lldbsuite.test.decorators import skipIfWindows, skipUnlessDarwin +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.dap_types import ( + CompileUnitsArgs, + LaunchArgs, + ModuleEvent, + ModuleReason, +) +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase -@skipIfTargetDoesNotSupportSharedLibraries() -class TestDAP_module(lldbdap_testcase.DAPTestCaseBase): - def run_test(self, symbol_basename, expect_debug_info_size): + +class TestDAP_module(DAPTestCaseBase): + def run_test(self, symbol_basename: str, expect_debug_info_size: bool): + session = self.build_and_create_session() program_basename = "a.out.stripped" program = self.getBuildArtifact(program_basename) - self.build_and_launch(program) - functions = ["foo"] - # This breakpoint will be resolved only when the libfoo module is loaded - breakpoint_ids = self.set_function_breakpoints( - functions, wait_for_resolve=False - ) - self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint") - self.continue_to_breakpoints(breakpoint_ids) - active_modules = self.dap_server.get_modules() + with session.configure(LaunchArgs(program)) as ctx: + # This breakpoint will be resolved only when the libfoo module is loaded. + breakpoints = session.set_function_breakpoints(["foo"]).body.breakpoints + self.assertEqual(len(breakpoints), 1, "expect one breakpoint.") + foo_bp_id = self.expect_not_none(breakpoints[0].id) + self.assertFalse(breakpoints[0].verified) + + session.verify_stopped_on_breakpoint(foo_bp_id, after=ctx.process_event) + active_modules = session.get_modules() program_module = active_modules[program_basename] self.assertIn( program_basename, active_modules, - "%s module is in active modules" % (program_basename), + f"{program_basename} module is in active modules", ) - self.assertIn("name", program_module, "make sure name is in module") - self.assertEqual(program_basename, program_module["name"]) - self.assertIn("path", program_module, "make sure path is in module") - self.assertEqual(program, program_module["path"]) - self.assertNotIn( - "symbolFilePath", - program_module, - "Make sure a.out.stripped has no debug info", + self.assertEqual(program_basename, program_module.name) + self.assertIsNotNone(program_module.path, "make sure path is in module") + self.assertEqual(program, program_module.path) + self.assertIsNone( + program_module.symbolFilePath, "Make sure a.out.stripped has no debug info" ) symbols_path = self.getBuildArtifact(symbol_basename) - self.dap_server.request_evaluate( - "`%s" % ('target symbols add -s "%s" "%s"' % (program, symbols_path)), - context="repl", + event_before_mod_change = session.last_event() + session.evaluate( + f'''`target symbols add -s "{program}" "{symbols_path}"''', context="repl" ) - def check_symbols_loaded_with_size(): - active_modules = self.dap_server.get_modules() - program_module = active_modules[program_basename] - self.assertIn("symbolFilePath", program_module) - self.assertIn(symbols_path, program_module["symbolFilePath"]) - size_regex = re.compile(r"[0-9]+(\.[0-9]*)?[KMG]?B") - return size_regex.match(program_module["debugInfoSize"]) + # Make sure we got an update event for the program module when the + # symbols got added. + changed_event = session.verify_next_module_event( + ModuleReason.CHANGED, after=event_before_mod_change + ) + changed_module = changed_event.body.module + self.assertEqual(program_module.name, changed_module.name) + self.assertIsNotNone(changed_module.symbolFilePath) + changed_symbols_path = self.expect_not_none(changed_module.symbolFilePath) + self.assertIn(symbols_path, changed_symbols_path) if expect_debug_info_size: - self.assertTrue( - self.wait_until(check_symbols_loaded_with_size), - "expect has debug info size", + changed_debug_size = self.expect_not_none(changed_module.debugInfoSize) + size_regex = re.compile(r"[0-9]+(\.[0-9]*)?[KMG]?B") + self.assertRegex( + changed_debug_size, size_regex, "expect has debug info size" ) - active_modules = self.dap_server.get_modules() + active_modules = session.get_modules() program_module = active_modules[program_basename] - self.assertEqual(program_basename, program_module["name"]) - self.assertEqual(program, program_module["path"]) - self.assertIn("addressRange", program_module) - - # Collect all the module names we saw as events. - module_new_names = [] - module_changed_names = [] - for module_event in self.dap_server.wait_for_module_events(): - reason = module_event["body"]["reason"] - if reason == "new": - module_new_names.append(module_event["body"]["module"]["name"]) - elif reason == "changed": - module_changed_names.append(module_event["body"]["module"]["name"]) + self.assertEqual(program_basename, program_module.name) + self.assertEqual(program, program_module.path) + self.assertIsNotNone(program_module.addressRange) + + # Collect all the modules added before we changed the program module. + new_module_names = [] + + def seen_module_changed_event(event: ModuleEvent): + if event.body.reason == ModuleReason.NEW: + new_module_names.append(event.body.module.name) + + return event.seq == changed_event.seq + + init_resp = ctx.init_response + session.wait_for_module_event(after=init_resp, until=seen_module_changed_event) # Make sure we got an event for every active module. - self.assertNotEqual(len(module_new_names), 0) + self.assertNotEqual(len(new_module_names), 0) for module in active_modules: - self.assertIn(module, module_new_names) + self.assertIn(module, new_module_names) - # Make sure we got an update event for the program module when the - # symbols got added. - self.assertNotEqual(len(module_changed_names), 0) - self.assertIn(program_module["name"], module_changed_names) - self.continue_to_exit() + session.continue_to_exit() @skipIfWindows def test_modules(self): @@ -112,18 +119,20 @@ def test_modules_dsym(self): @skipIfWindows def test_compile_units(self): + session = self.build_and_create_session() program = self.getBuildArtifact("a.out") - self.build_and_launch(program) source = "main.cpp" main_source_path = self.getSourcePath(source) - breakpoint1_line = line_number(source, "// breakpoint 1") - lines = [breakpoint1_line] - breakpoint_ids = self.set_source_breakpoints(source, lines) - self.continue_to_breakpoints(breakpoint_ids) - moduleId = self.dap_server.get_modules()["a.out"]["id"] - response = self.dap_server.request_compileUnits(moduleId) - self.assertTrue(response["body"]) - cu_paths = [cu["compileUnitPath"] for cu in response["body"]["compileUnits"]] + with session.configure(LaunchArgs(program)) as ctx: + breakpoint1_line = line_number(source, "// breakpoint 1") + bp_ids = session.resolve_source_breakpoints(source, [breakpoint1_line]) + process_event = ctx.process_event + + session.verify_stopped_on_breakpoint(bp_ids, after=process_event) + + module_id = session.get_modules()["a.out"].id + response = session.send_request(CompileUnitsArgs(module_id)).result() + cu_paths = [cu.compileUnitPath for cu in response.body.compileUnits] self.assertIn(main_source_path, cu_paths, "Real path to main.cpp matches") - self.continue_to_exit() + session.continue_to_exit() diff --git a/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py b/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py index 2336b9f2a5a1a..5a1edeb679bc5 100644 --- a/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py +++ b/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py @@ -2,11 +2,12 @@ Test lldb-dap moduleSymbols request """ -import lldbdap_testcase -from lldbsuite.test.decorators import * +from lldbsuite.test.decorators import skipIfWindows +from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs, ModuleSymbolsArgs +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase -class TestDAP_moduleSymbols(lldbdap_testcase.DAPTestCaseBase): +class TestDAP_moduleSymbols(DAPTestCaseBase): # On windows LLDB doesn't recognize symbols in a.out. @skipIfWindows def test_moduleSymbols(self): @@ -14,27 +15,24 @@ def test_moduleSymbols(self): Test that the moduleSymbols request returns correct symbols from the module. """ program = self.getBuildArtifact("a.out") - self.build_and_launch(program) + session = self.build_and_create_session() + session.launch(LaunchArgs(program=program)) - symbol_names = [] - i = 0 + symbol_names = set() + start = 0 + page_size = 100 while True: - next_symbol = self.dap_server.request_moduleSymbols( - moduleName="a.out", startIndex=i, count=1 + module_sym_args = ModuleSymbolsArgs( + moduleName="a.out", startIndex=start, count=page_size ) - self.assertIn("symbols", next_symbol["body"]) - result_symbols = next_symbol["body"]["symbols"] - self.assertLessEqual(len(result_symbols), 1) - if len(result_symbols) == 0: - break + response = session.send_request(module_sym_args).result() + symbols = response.body.symbols + symbol_names.update(sym.name for sym in symbols) - self.assertIn("name", result_symbols[0]) - symbol_names.append(result_symbols[0]["name"]) - i += 1 - if i >= 1000: + if len(symbols) < page_size: break + start += page_size - self.assertGreater(len(symbol_names), 0) self.assertIn("main", symbol_names) self.assertIn("func1", symbol_names) self.assertIn("func2", symbol_names) diff --git a/lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp b/lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp index 5f9332e3e85bd..06176de68a336 100644 --- a/lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp +++ b/lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp @@ -66,6 +66,23 @@ TEST_P(ABIAArch64TestFixture, AugmentRegisterInfo) { EXPECT_EQ(new_pc.regnum_dwarf, arm64_dwarf::pc); } +TEST_P(ABIAArch64TestFixture, AugmentRegisterInfoThreadPointer) { + ABISP abi_sp = ABI::FindPlugin(ProcessSP(), ArchSpec(GetParam())); + ASSERT_TRUE(abi_sp); + using Register = DynamicRegisterInfo::Register; + + Register tpidr; + tpidr.name = ConstString("tpidr"); + tpidr.set_name = ConstString("GPR"); + std::vector regs{tpidr}; + + abi_sp->AugmentRegisterInfo(regs); + + ASSERT_EQ(regs.size(), 1U); + EXPECT_EQ(regs[0].regnum_generic, + static_cast(LLDB_REGNUM_GENERIC_TP)); +} + INSTANTIATE_TEST_SUITE_P(ABIAArch64Tests, ABIAArch64TestFixture, testing::Values("aarch64-pc-linux", "arm64-apple-macosx")); diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp index 042045f35552c..f552f42dcba5c 100644 --- a/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -445,6 +445,14 @@ TEST(DWARFExpression, DW_OP_convert) { Form: DW_FORM_data1 - Attribute: DW_AT_byte_size Form: DW_FORM_data1 + - Code: 0x00000003 + Tag: DW_TAG_enumeration_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_encoding + Form: DW_FORM_data1 + - Attribute: DW_AT_byte_size + Form: DW_FORM_data1 debug_info: - Version: 4 AddrSize: 8 @@ -493,15 +501,21 @@ TEST(DWARFExpression, DW_OP_convert) { Values: - Value: 0x000000000000000b # DW_ATE_numeric_string - Value: 0x0000000000000001 + # 0x00000020: + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000007 # DW_ATE_unsigned + - Value: 0x0000000000000004 - AbbrCode: 0x00000000 )"; - // Compile unit relative offsets to each DW_TAG_base_type + // Compile unit relative offsets to type DIEs. uint8_t offs_uint32_t = 0x0000000e; uint8_t offs_uint64_t = 0x00000011; uint8_t offs_sint64_t = 0x00000014; uint8_t offs_uchar = 0x00000017; uint8_t offs_schar = 0x0000001a; + uint8_t offs_enum = 0x00000020; DWARFExpressionTester t(yamldata, /*cu_index=*/1); ASSERT_TRUE((bool)t.GetDwarfUnit()); @@ -575,6 +589,12 @@ TEST(DWARFExpression, DW_OP_convert) { t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x1d}).takeError(), llvm::Failed()); + // Not a DW_TAG_base_type. + EXPECT_THAT_ERROR( + t.Eval({DW_OP_const1s, 'X', DW_OP_convert, offs_enum}).takeError(), + llvm::FailedWithMessage( + "DW_OP_convert type DIE is not a DW_TAG_base_type")); + // A non-zero DIE offset with no DWARF unit. EXPECT_THAT_ERROR( Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x01}, nullptr, nullptr) diff --git a/lldb/unittests/Host/JSONTransportTest.cpp b/lldb/unittests/Host/JSONTransportTest.cpp index 3e977a70f5d4e..afa59b81ae315 100644 --- a/lldb/unittests/Host/JSONTransportTest.cpp +++ b/lldb/unittests/Host/JSONTransportTest.cpp @@ -780,6 +780,57 @@ TEST_F(TransportBinderTest, InBoundRequestsVoidParamsAndResult) { EXPECT_TRUE(called); } +// In-bound asynchronous request handler that defers its reply. +TEST_F(TransportBinderTest, InBoundAsyncRequests) { + Reply saved_reply; + MyFnParams saved_params; + binder->BindAsync( + "add", [&](const MyFnParams ¶ms, Reply reply) { + saved_params = params; + saved_reply = std::move(reply); + }); + + EXPECT_THAT_ERROR(from_remote->Send(Request{1, "add", MyFnParams{3, 4}}), + Succeeded()); + // The handler runs but does not reply, so no response is sent yet. + Run(); + ASSERT_TRUE(static_cast(saved_reply)); + EXPECT_EQ(saved_params.a, 3); + EXPECT_EQ(saved_params.b, 4); + + // Replying later sends the response. + saved_reply(MyFnResult{7}); + EXPECT_CALL(remote, Received(Response{1, 0, MyFnResult{7}})); + Run(); +} + +TEST_F(TransportBinderTest, InBoundAsyncRequestsVoidParams) { + Reply saved_reply; + binder->BindAsync( + "ping", [&](Reply reply) { saved_reply = std::move(reply); }); + + EXPECT_THAT_ERROR(from_remote->Send(Request{2, "ping", std::nullopt}), + Succeeded()); + Run(); + ASSERT_TRUE(static_cast(saved_reply)); + + saved_reply(MyFnResult{5}); + EXPECT_CALL(remote, Received(Response{2, 0, MyFnResult{5}})); + Run(); +} + +TEST_F(TransportBinderTest, InBoundAsyncRequestsError) { + binder->BindAsync( + "add", [&](const MyFnParams &, Reply reply) { + reply(llvm::createStringError("nope")); + }); + + EXPECT_THAT_ERROR(from_remote->Send(Request{3, "add", MyFnParams{1, 2}}), + Succeeded()); + EXPECT_CALL(remote, Received(Response{3, 1, "nope"})); + Run(); +} + // Out-bound binding event handler. TEST_F(TransportBinderTest, OutBoundEvents) { OutgoingEvent emitEvent = binder->Bind("evt"); diff --git a/lldb/unittests/Protocol/CMakeLists.txt b/lldb/unittests/Protocol/CMakeLists.txt index 78953b1b95ae8..1e9b02d735544 100644 --- a/lldb/unittests/Protocol/CMakeLists.txt +++ b/lldb/unittests/Protocol/CMakeLists.txt @@ -1,4 +1,5 @@ add_lldb_unittest(ProtocolTests + MCPClientTest.cpp MCPErrorTest.cpp MCPPluginTest.cpp MCPServerInfoTest.cpp diff --git a/lldb/unittests/Protocol/MCPClientTest.cpp b/lldb/unittests/Protocol/MCPClientTest.cpp new file mode 100644 index 0000000000000..c7fa7bb93d9c3 --- /dev/null +++ b/lldb/unittests/Protocol/MCPClientTest.cpp @@ -0,0 +1,223 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "ProtocolMCPTestUtilities.h" // IWYU pragma: keep +#include "TestingSupport/Host/JSONTransportTestUtilities.h" +#include "TestingSupport/SubsystemRAII.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Host/MainLoop.h" +#include "lldb/Host/MainLoopBase.h" +#include "lldb/Host/Socket.h" +#include "lldb/Protocol/MCP/Client.h" +#include "lldb/Protocol/MCP/MCPError.h" +#include "lldb/Protocol/MCP/Protocol.h" +#include "lldb/Protocol/MCP/Resource.h" +#include "lldb/Protocol/MCP/Server.h" +#include "lldb/Protocol/MCP/Tool.h" +#include "lldb/Protocol/MCP/Transport.h" +#include "llvm/Support/Error.h" +#include "llvm/Testing/Support/Error.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include +#include + +using namespace llvm; +using namespace lldb_private; +using namespace lldb_private::transport; +using namespace lldb_protocol::mcp; + +// Flakey, see https://github.com/llvm/llvm-project/issues/152677. +#ifndef _WIN32 + +namespace { + +/// A tool that echoes a fixed string. +class EchoTool : public Tool { +public: + using Tool::Tool; + + llvm::Expected Call(const ToolArguments &) override { + CallToolResult result; + result.content.emplace_back(TextContent{{"echo"}}); + return result; + } +}; + +/// A tool that fails with an MCP error. +class ErrorTool : public Tool { +public: + using Tool::Tool; + + llvm::Expected Call(const ToolArguments &) override { + return llvm::createStringError("boom"); + } +}; + +class TestResourceProvider : public ResourceProvider { +public: + using ResourceProvider::ResourceProvider; + + std::vector GetResources() const override { + Resource resource; + resource.uri = "lldb://foo/bar"; + resource.name = "name"; + resource.description = "description"; + resource.mimeType = "application/json"; + return {resource}; + } + + llvm::Expected + ReadResource(llvm::StringRef uri) const override { + if (uri != "lldb://foo/bar") + return llvm::make_error(uri.str()); + + TextResourceContents contents; + contents.uri = "lldb://foo/bar"; + contents.mimeType = "application/json"; + contents.text = "foobar"; + + ReadResourceResult result; + result.contents.push_back(contents); + return result; + } +}; + +class MCPClientTest : public testing::Test { +public: + SubsystemRAII subsystems; + + MainLoop loop; + std::unique_ptr server; + std::unique_ptr client; + TestTransport *client_transport = nullptr; + + void SetUp() override { + auto pair = TestTransport::createConnectedPair(loop); + client_transport = pair.first.get(); + + server = std::make_unique("lldb-mcp", "0.1.0"); + server->AddTool(std::make_unique("echo", "echo tool")); + server->AddTool(std::make_unique("error", "error tool")); + server->AddResourceProvider(std::make_unique()); + EXPECT_THAT_ERROR(server->Accept(std::move(pair.second)), Succeeded()); + + client = std::make_unique(std::move(pair.first)); + EXPECT_THAT_ERROR(client->Run(), Succeeded()); + } + + /// Runs the MainLoop, draining pending callbacks. + void Run() { + bool addition_succeeded = loop.AddPendingCallback( + [](MainLoopBase &loop) { loop.RequestTermination(); }); + EXPECT_TRUE(addition_succeeded); + EXPECT_THAT_ERROR(loop.Run().takeError(), Succeeded()); + } + + /// Issues an asynchronous request and returns its captured result. + template + llvm::Expected + Capture(llvm::unique_function)> invoke) { + std::promise> promised_result; + invoke([&promised_result](llvm::Expected result) { + promised_result.set_value(std::move(result)); + }); + Run(); + return promised_result.get_future().get(); + } +}; + +} // namespace + +TEST_F(MCPClientTest, Initialize) { + llvm::Expected result = + Capture([&](Client::Reply reply) { + client->Initialize( + InitializeParams{/*protocolVersion=*/"2024-11-05", + /*capabilities=*/{}, + /*clientInfo=*/{"lldb-unit", "0.1.0"}}, + std::move(reply)); + }); + ASSERT_THAT_EXPECTED(result, Succeeded()); + EXPECT_EQ(result->protocolVersion, "2024-11-05"); + EXPECT_EQ(result->serverInfo.name, "lldb-mcp"); + EXPECT_EQ(result->serverInfo.version, "0.1.0"); + EXPECT_TRUE(result->capabilities.supportsToolsList); + EXPECT_TRUE(result->capabilities.supportsResourcesList); +} + +TEST_F(MCPClientTest, ToolsList) { + llvm::Expected result = + Capture([&](Client::Reply reply) { + client->ToolsList(std::move(reply)); + }); + ASSERT_THAT_EXPECTED(result, Succeeded()); + EXPECT_THAT(result->tools, testing::SizeIs(2)); +} + +TEST_F(MCPClientTest, ToolsCall) { + llvm::Expected result = + Capture([&](Client::Reply reply) { + client->ToolsCall(CallToolParams{/*name=*/"echo", /*arguments=*/{}}, + std::move(reply)); + }); + ASSERT_THAT_EXPECTED(result, Succeeded()); + ASSERT_THAT(result->content, testing::SizeIs(1)); + EXPECT_EQ(result->content.front().text, "echo"); + EXPECT_FALSE(result->isError); +} + +TEST_F(MCPClientTest, ToolsCallError) { + llvm::Expected result = + Capture([&](Client::Reply reply) { + client->ToolsCall(CallToolParams{/*name=*/"error", /*arguments=*/{}}, + std::move(reply)); + }); + EXPECT_THAT_EXPECTED(result, FailedWithMessage("boom")); +} + +TEST_F(MCPClientTest, ResourcesList) { + llvm::Expected result = Capture( + [&](Client::Reply reply) { + client->ResourcesList(std::move(reply)); + }); + ASSERT_THAT_EXPECTED(result, Succeeded()); + ASSERT_THAT(result->resources, testing::SizeIs(1)); + EXPECT_EQ(result->resources.front().uri, "lldb://foo/bar"); +} + +TEST_F(MCPClientTest, ResourcesRead) { + llvm::Expected result = + Capture([&](Client::Reply reply) { + client->ResourcesRead(ReadResourceParams{/*uri=*/"lldb://foo/bar"}, + std::move(reply)); + }); + ASSERT_THAT_EXPECTED(result, Succeeded()); + ASSERT_THAT(result->contents, testing::SizeIs(1)); + EXPECT_EQ(result->contents.front().text, "foobar"); +} + +TEST_F(MCPClientTest, DisconnectHandler) { + bool disconnected = false; + client->SetDisconnectHandler([&]() { disconnected = true; }); + + client_transport->SimulateClosed(); + EXPECT_TRUE(disconnected); +} + +TEST_F(MCPClientTest, ErrorHandler) { + std::string message; + client->SetErrorHandler( + [&](llvm::Error error) { message = llvm::toString(std::move(error)); }); + + client_transport->SimulateError(llvm::createStringError("kaboom")); + EXPECT_EQ(message, "kaboom"); +} + +#endif // ifndef _WIN32 diff --git a/lldb/unittests/Protocol/ProtocolMCPTest.cpp b/lldb/unittests/Protocol/ProtocolMCPTest.cpp index efed243912c00..51ad8ef21033b 100644 --- a/lldb/unittests/Protocol/ProtocolMCPTest.cpp +++ b/lldb/unittests/Protocol/ProtocolMCPTest.cpp @@ -61,6 +61,10 @@ TEST(ProtocolMCPTest, Notification) { TEST(ProtocolMCPTest, ServerCapabilities) { ServerCapabilities capabilities; capabilities.supportsToolsList = true; + capabilities.supportsResourcesList = true; + capabilities.supportsResourcesSubscribe = true; + capabilities.supportsCompletions = true; + capabilities.supportsLogging = true; llvm::Expected deserialized_capabilities = roundtripJSON(capabilities); @@ -68,6 +72,14 @@ TEST(ProtocolMCPTest, ServerCapabilities) { EXPECT_EQ(capabilities.supportsToolsList, deserialized_capabilities->supportsToolsList); + EXPECT_EQ(capabilities.supportsResourcesList, + deserialized_capabilities->supportsResourcesList); + EXPECT_EQ(capabilities.supportsResourcesSubscribe, + deserialized_capabilities->supportsResourcesSubscribe); + EXPECT_EQ(capabilities.supportsCompletions, + deserialized_capabilities->supportsCompletions); + EXPECT_EQ(capabilities.supportsLogging, + deserialized_capabilities->supportsLogging); } TEST(ProtocolMCPTest, TextContent) { diff --git a/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt b/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt index 88492188e794b..185cad60f74d9 100644 --- a/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ b/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt @@ -28,6 +28,7 @@ add_lldb_unittest(SymbolFileDWARFTests set(test_inputs test-dwarf.exe DW_AT_default_value-test.yaml - DW_AT_spec_decl_exists-test.yaml) + DW_AT_spec_decl_exists-test.yaml + DW_TAG_variant_rust-test.yaml) add_unittest_inputs(SymbolFileDWARFTests "${test_inputs}") diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp index a95d6ecfab790..4d4dc57816694 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -667,14 +667,14 @@ TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) { debug_str: - Foo - debug_line: + debug_line: - Version: 4 MinInstLength: 1 MaxOpsPerInst: 1 DefaultIsStmt: 1 LineBase: 0 LineRange: 0 - Files: + Files: - Name: main.cpp DirIdx: 0 ModTime: 0 @@ -2118,3 +2118,35 @@ TEST_F(DWARFASTParserClangTests, EXPECT_EQ(type_sp->GetName(), "Bar"); EXPECT_EQ(type_sp->GetForwardCompilerType().GetTypeName(), "Foo::Bar"); } + +TEST_F(DWARFASTParserClangTests, TestRustVariantMember) { + // Tests that 128-bit discriminants are output to variant names correctly. + auto yamldata = llvm::MemoryBuffer::getFile( + GetInputFilePath("DW_TAG_variant_rust-test.yaml"), /*IsText=*/true); + ASSERT_TRUE(yamldata); + + DWARFASTParserClangYAMLTester tester(yamldata->get()->getBuffer()); + + auto &ts_clang = tester.GetTypeSystem(); + auto *symbol_file = ts_clang.GetSymbolFile(); + + TypeQuery query{ConstString("BigDiscr")}; + TypeResults result{}; + symbol_file->FindTypes(query, result); + + auto type = result.GetFirstType(); + auto enum_type = type.get()->GetFullCompilerType(); + std::string f_name; + auto all_variants = + enum_type.GetFieldAtIndex(0, f_name, nullptr, nullptr, nullptr); + ASSERT_EQ(f_name, "$variants$"); + + f_name.clear(); + all_variants.GetFieldAtIndex(0, f_name, nullptr, nullptr, nullptr); + ASSERT_EQ(f_name, "$variant$0"); + + all_variants.GetFieldAtIndex(1, f_name, nullptr, nullptr, nullptr); + // 0x16151413121110090807060504030201 == + // 29352461300415899028694309177919734273 + ASSERT_EQ(f_name, "$variant$29352461300415899028694309177919734273"); +} diff --git a/lldb/unittests/SymbolFile/DWARF/Inputs/DW_TAG_variant_rust-test.yaml b/lldb/unittests/SymbolFile/DWARF/Inputs/DW_TAG_variant_rust-test.yaml new file mode 100644 index 0000000000000..b7089e362cf13 --- /dev/null +++ b/lldb/unittests/SymbolFile/DWARF/Inputs/DW_TAG_variant_rust-test.yaml @@ -0,0 +1,871 @@ +# Below code compiled with rustc src/main.rs --target=x86_64-unknown-linux-gnu -g -C panic=abort +# +# #![no_std] +# #![no_main] +# +# #[allow(unused)] +# #[repr(u128)] +# enum BigDiscr { +# Value(u64), +# None = 0x16151413121110090807060504030201, +# } +# +# fn use_it(_: &BigDiscr) {} +# +# #[panic_handler] +# fn panic(_info: &core::panic::PanicInfo) -> ! { +# loop {} +# } +# +# #[unsafe(no_mangle)] +# extern "C" fn main() { +# let none = BigDiscr::None; +# let some = BigDiscr::Value(31); +# +# use_it(&none); +# use_it(&some); +# } + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x4 + - Name: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: 48897C24F8EBFE + - Name: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: 48897C24F8C3 + - Name: .text.main + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: 4883EC4848B80910111213141516488944240848B801020304050607084889042448C74424301F00000048C74424280000000048C7442420000000004889E7E800000000488D7C2420E8000000004883C448C3 + - Name: .debug_gdb_scripts + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 016764625F6C6F61645F727573745F7072657474795F7072696E746572732E707900 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 011101250E1305030E10171B0E110155170000023901030E0000032E011101120640186E0E030E3A0B3B0B87011900000405000218030E3A0B3B0B49130000052E011101120640186E0E030E3A0B3B0B000006050002183A0B3B0B49130000072E01110112064018030E3A0B3B0B3F190000080B011101120600000934000218030E88010F3A0B3B0B491300000A1301030E0B0B320B88010F00000B3301151300000C0D00491388010F380B341900000D1901160A00000E0D00030E491388010F380B00000F0D00030E491388010F380B320B0000101300030E0B0B320B88010F0000110F004913030E330600001219010000131901160B0000142F004913030E0000152400030E3E0B0B0B00001615014913000017050049130000181301030E0B0B88010F0000190F004913330600001A1300030E0B0B88010F00001B0101491300001C21004913220D370B00001D2400030E0B0B3E0B000000 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 5F0500000400000000000801000000001C0000000000000000000000000000000000000000000000000002000000000300000000000000000700000001570000000000000000010E0402917800000000010E3B010000000500000000000000000600000001570000000000000000010B06029178010B4E050000000700000000000000005300000001570000000001130800000000000000002D0000000902910000000000100114CB000000080000000000000000120000000902912000000000100115CB0000000000000A000000002003100BD80000000C5B05000010000D10000000000000000000000000000000000E000000001C0100001000000D10010203040506070809101112131415160E0000000031010000100000000A000000002003100F00000000320400000810030010000000002003100000115701000000000000000000000200000000020000000002000000000A000000001801080F00000000110400000800030F00000000F50400000808030F00000000470500000110030F0000000047050000011103000002000000000A000000001801080F00000000400300000800030F00000000770400000410030F00000000770400000414030F00000000FD03000001180300000002000000000A000000001001080F00000000E60200000800030F00000000040300000808030002000000000A000000001001080F0000000011020000080003000A000000001003080B1E0200000C320400000800120E000000004102000008000013000E000000006E020000080000000A000000001003080F00000000220300000800030F000000004D0400000808030F00000000EB030000011003000A000000001003080F000000007E04000002080300000010000000000001010A000000001801080F00000000AE0200000410030F0000000085040000080003000A000000000801040F00000000770400000400030F000000007E0400000204030F000000007E0400000206030000020000000002000000000A00000000080108141E040000000000000F0000000025040000080003000A0000000008010814FC010000000000000F00000000E8040000080003000A000000000801081439040000000000000F0000000040040000080003000A00000000100108141E040000000000000F000000000205000008000300000002000000000A000000000101010B720300000C1E040000010013000E000000009603000001000013010E00000000BD030000010000000A000000000101011439040000000000001485020000000000000F0000000039040000010101000A000000000101011439040000000000001485020000000000000F000000008502000001010100000002000000000A0000000000010114DB04000000000000000A0000000000010114290500000000000000000011D6010000000000000000000015000000000701111E0400000000000000000000150000000007081500000000070011390400000000000000000000115A040000000000000000000016650300001722030000176A04000000118D02000000000000000000001500000000070415000000000702180000000010080E00000000A304000008000E00000000B304000008080019AC040000000000001A00000000000111C004000000000000000000001BCD0400001CD4040000000600150000000007081D0000000008071139040000000000000000000011FC010000000000000000000011960100000000000000000000180000000010080E000000002005000008000E00000000CD040000080800191E04000000000000180000000010080E000000002005000008000E00000000CD0400000808001500000000020111CB00000000000000000000001500000000071000 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 0072757374632076657273696F6E20312E39332E30202832353462353936303720323032362D30312D31392900 + - Name: .note.GNU-stack + Type: SHT_PROGBITS + AddressAlign: 0x1 + - Name: .eh_frame + Type: SHT_X86_64_UNWIND + Flags: [ SHF_ALLOC ] + AddressAlign: 0x8 + Content: 1400000000000000017A5200017810011B0C070890010000100000001C00000000000000070000000000000010000000300000000000000006000000000000001400000044000000000000005300000000440E50024E0E08 + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 79000000040023000000010101FB0E0D00010101010000000100000173726300006D61696E2E727300010000000009020000000000000000030D0105050A5902020001010009020000000000000000030A01051B0A580201000101000902000000000000000003120105100AD7082F050508A08305020B9F0205000101 + - Name: .rela.text.main + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .text.main + Relocations: + - Offset: 0x40 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_PLT32 + Addend: -4 + - Offset: 0x4A + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_PLT32 + Addend: -4 + - Name: .rela.debug_info + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .debug_info + Relocations: + - Offset: 0x6 + Symbol: .debug_abbrev + Type: R_X86_64_32 + - Offset: 0xC + Symbol: .debug_str + Type: R_X86_64_32 + - Offset: 0x12 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 57 + - Offset: 0x16 + Symbol: .debug_line + Type: R_X86_64_32 + - Offset: 0x1A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 99 + - Offset: 0x26 + Symbol: .debug_ranges + Type: R_X86_64_32 + - Offset: 0x2B + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 147 + - Offset: 0x30 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + - Offset: 0x3E + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 152 + - Offset: 0x42 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 199 + - Offset: 0x4C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 248 + - Offset: 0x58 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + - Offset: 0x66 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 205 + - Offset: 0x6A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 241 + - Offset: 0x7C + Symbol: .text.main + Type: R_X86_64_64 + - Offset: 0x8A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 147 + - Offset: 0x91 + Symbol: .text.main + Type: R_X86_64_64 + Addend: 33 + - Offset: 0xA1 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1193 + - Offset: 0xAD + Symbol: .text.main + Type: R_X86_64_64 + Addend: 60 + - Offset: 0xBD + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1198 + - Offset: 0xCC + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1168 + - Offset: 0xF2 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1157 + - Offset: 0x110 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1163 + - Offset: 0x11D + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1157 + - Offset: 0x125 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 425 + - Offset: 0x132 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1163 + - Offset: 0x140 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1116 + - Offset: 0x149 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 254 + - Offset: 0x14E + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 199 + - Offset: 0x153 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 259 + - Offset: 0x158 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1106 + - Offset: 0x160 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 270 + - Offset: 0x16C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 929 + - Offset: 0x178 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1071 + - Offset: 0x184 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1087 + - Offset: 0x192 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 929 + - Offset: 0x197 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1029 + - Offset: 0x19F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 938 + - Offset: 0x1AB + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 987 + - Offset: 0x1B7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 992 + - Offset: 0x1C3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 996 + - Offset: 0x1D2 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 278 + - Offset: 0x1D7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 897 + - Offset: 0x1DF + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 282 + - Offset: 0x1EB + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 339 + - Offset: 0x1F8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 344 + - Offset: 0x1FD + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 824 + - Offset: 0x205 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 347 + - Offset: 0x212 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 811 + - Offset: 0x227 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 354 + - Offset: 0x235 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 805 + - Offset: 0x242 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 354 + - Offset: 0x24A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 366 + - Offset: 0x256 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 397 + - Offset: 0x262 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 767 + - Offset: 0x26F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 805 + - Offset: 0x277 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 425 + - Offset: 0x286 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 417 + - Offset: 0x28E + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 614 + - Offset: 0x296 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 462 + - Offset: 0x2A2 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 518 + - Offset: 0x2AF + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 500 + - Offset: 0x2B7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 470 + - Offset: 0x2C3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 480 + - Offset: 0x2CF + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 490 + - Offset: 0x2DD + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 291 + - Offset: 0x2E2 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 295 + - Offset: 0x2E7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 327 + - Offset: 0x2F3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x2F8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x305 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 864 + - Offset: 0x311 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x316 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x323 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 385 + - Offset: 0x32F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x334 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x341 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 974 + - Offset: 0x34D + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x352 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x361 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 407 + - Offset: 0x366 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 433 + - Offset: 0x37C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 414 + - Offset: 0x38A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 429 + - Offset: 0x397 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 414 + - Offset: 0x3A3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x3AC + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 423 + - Offset: 0x3B1 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 425 + - Offset: 0x3BE + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 429 + - Offset: 0x3CA + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x3D3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 423 + - Offset: 0x3D8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 425 + - Offset: 0x3E7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 777 + - Offset: 0x3EC + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 788 + - Offset: 0x3F8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x3FE + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1011 + - Offset: 0x40A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x416 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 907 + - Offset: 0x41F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 304 + - Offset: 0x42A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 317 + - Offset: 0x433 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 350 + - Offset: 0x43A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 372 + - Offset: 0x445 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 375 + - Offset: 0x452 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 650 + - Offset: 0x46F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 624 + - Offset: 0x478 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 476 + - Offset: 0x47F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 486 + - Offset: 0x486 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 588 + - Offset: 0x48D + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x498 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 543 + - Offset: 0x4AD + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 522 + - Offset: 0x4B8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 576 + - Offset: 0x4CE + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 550 + - Offset: 0x4D5 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 556 + - Offset: 0x4E0 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 784 + - Offset: 0x4ED + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 833 + - Offset: 0x4FA + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1038 + - Offset: 0x503 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 963 + - Offset: 0x50A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 947 + - Offset: 0x515 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 956 + - Offset: 0x52A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1006 + - Offset: 0x531 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 947 + - Offset: 0x53C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 956 + - Offset: 0x548 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1082 + - Offset: 0x553 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1177 + - Offset: 0x55C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1152 + - Name: .rela.debug_aranges + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .debug_aranges + Relocations: + - Offset: 0x6 + Symbol: .debug_info + Type: R_X86_64_32 + - Offset: 0x10 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + - Offset: 0x20 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + - Offset: 0x30 + Symbol: .text.main + Type: R_X86_64_64 + - Name: .rela.debug_ranges + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .debug_ranges + Relocations: + - Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + - Offset: 0x8 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + Addend: 7 + - Offset: 0x10 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + - Offset: 0x18 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + Addend: 6 + - Offset: 0x20 + Symbol: .text.main + Type: R_X86_64_64 + - Offset: 0x28 + Symbol: .text.main + Type: R_X86_64_64 + Addend: 83 + - Name: .rela.eh_frame + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .eh_frame + Relocations: + - Offset: 0x20 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_PC32 + - Offset: 0x34 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_PC32 + - Offset: 0x48 + Symbol: .text.main + Type: R_X86_64_PC32 + - Name: .rela.debug_line + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .debug_line + Relocations: + - Offset: 0x30 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + - Offset: 0x47 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + - Offset: 0x5E + Symbol: .text.main + Type: R_X86_64_64 + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: .text + - Name: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + - Name: .text._ZN4main6use_it17h7beb6f96865c87acE + - Name: .text.main + - Name: .rela.text.main + - Name: .debug_gdb_scripts + - Name: .debug_abbrev + - Name: .debug_info + - Name: .rela.debug_info + - Name: .debug_aranges + - Name: .rela.debug_aranges + - Name: .debug_ranges + - Name: .rela.debug_ranges + - Name: .debug_str + - Name: .comment + - Name: .note.GNU-stack + - Name: .eh_frame + - Name: .rela.eh_frame + - Name: .debug_line + - Name: .rela.debug_line + - Name: .symtab +Symbols: + - Name: main.9b5cc465332d101d-cgu.0 + Type: STT_FILE + Index: SHN_ABS + - Name: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: STT_SECTION + Section: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + - Name: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: STT_SECTION + Section: .text._ZN4main6use_it17h7beb6f96865c87acE + - Name: _ZN4main6use_it17h7beb6f96865c87acE + Type: STT_FUNC + Section: .text._ZN4main6use_it17h7beb6f96865c87acE + Size: 0x6 + - Name: .text.main + Type: STT_SECTION + Section: .text.main + - Name: .debug_abbrev + Type: STT_SECTION + Section: .debug_abbrev + - Name: .debug_info + Type: STT_SECTION + Section: .debug_info + - Name: .debug_ranges + Type: STT_SECTION + Section: .debug_ranges + - Name: .debug_str + Type: STT_SECTION + Section: .debug_str + - Name: .debug_line + Type: STT_SECTION + Section: .debug_line + - Name: _RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: STT_FUNC + Section: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Binding: STB_GLOBAL + Size: 0x7 + Other: [ STV_HIDDEN ] + - Name: main + Type: STT_FUNC + Section: .text.main + Binding: STB_GLOBAL + Size: 0x53 + - Name: __rustc_debug_gdb_scripts_section__ + Type: STT_OBJECT + Section: .debug_gdb_scripts + Binding: STB_WEAK + Size: 0x22 +DWARF: + debug_str: + - 'clang LLVM (rustc version 1.93.0 (254b59607 2026-01-19))' + - 'src/main.rs\@\main.9b5cc465332d101d-cgu.0' + - 'C:\Coding\NotMyCode\llvm_patches\llvm-project\z' + - main + - _RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + - panic + - _ZN4main6use_it17h7beb6f96865c87acE + - use_it + - _info + - core + - panic_info + - message + - fmt + - template + - ptr + - non_null + - u8 + - T + - pointer + - '*const u8' + - 'NonNull' + - args + - rt + - ty + - u64 + - Placeholder + - value + - '()' + - '*const ()' + - 'NonNull<()>' + - formatter + - result + - Ok + - Error + - E + - __0 + - Err + - 'Result<(), core::fmt::Error>' + - options + - flags + - u32 + - width + - u16 + - precision + - FormattingOptions + - buf + - 'dyn core::fmt::Write' + - vtable + - usize + - __ARRAY_SIZE_TYPE__ + - '&[usize; 6]' + - '&mut dyn core::fmt::Write' + - Formatter + - '&mut core::fmt::Formatter' + - 'unsafe fn(core::ptr::non_null::NonNull<()>, &mut core::fmt::Formatter) -> core::result::Result<(), core::fmt::Error>' + - _lifetime + - marker + - '&()' + - 'PhantomData<&()>' + - Count + - ArgumentType + - Argument + - '*const core::fmt::rt::Argument' + - 'NonNull' + - Arguments + - '&core::fmt::Arguments' + - location + - filename + - data_ptr + - length + - '*const str' + - 'NonNull' + - line + - col + - _filename + - '&str' + - 'PhantomData<&str>' + - Location + - '&core::panic::location::Location' + - can_unwind + - bool + - force_no_backtrace + - PanicInfo + - '&core::panic::panic_info::PanicInfo' + - u128 + - Value + - None + - BigDiscr + - '&main::BigDiscr' + - none + - some + debug_aranges: + - Length: 0x4C + Version: 2 + CuOffset: 0x0 + AddressSize: 0x8 + Descriptors: + - Address: 0x0 + Length: 0x7 + - Address: 0x0 + Length: 0x6 + - Address: 0x0 + Length: 0x53 + debug_ranges: + - Offset: 0x0 + AddrSize: 0x8 + Entries: [] + - Offset: 0x10 + AddrSize: 0x8 + Entries: [] + - Offset: 0x20 + AddrSize: 0x8 + Entries: [] + - Offset: 0x30 + AddrSize: 0x8 + Entries: [] +... diff --git a/lldb/unittests/TestingSupport/Host/JSONTransportTestUtilities.h b/lldb/unittests/TestingSupport/Host/JSONTransportTestUtilities.h index 93845fc82d173..6fc67a2b6c8d6 100644 --- a/lldb/unittests/TestingSupport/Host/JSONTransportTestUtilities.h +++ b/lldb/unittests/TestingSupport/Host/JSONTransportTestUtilities.h @@ -37,28 +37,46 @@ class TestTransport final return std::make_pair(std::move(transports[0]), std::move(transports[1])); } + /// Creates a cross-wired pair, where a message sent on one transport is + /// delivered to the other's registered handler. This mirrors a real + /// connected transport pair (bytes written to one end arrive at the other), + /// unlike createPair() where a sent message is delivered back to the sender's + /// own handler. + static std::pair>, + std::unique_ptr>> + createConnectedPair(lldb_private::MainLoop &loop) { + auto a = std::make_unique>(loop); + auto b = std::make_unique>(loop); + a->m_peer = b.get(); + b->m_peer = a.get(); + return std::make_pair(std::move(a), std::move(b)); + } + explicit TestTransport(lldb_private::MainLoop &loop) : m_loop(loop) {} llvm::Error Send(const typename Proto::Evt &evt) override { - EXPECT_TRUE(m_handler) << "Send called before RegisterMessageHandler"; + EXPECT_TRUE(Target()) << "Send called before RegisterMessageHandler"; m_loop.AddPendingCallback([this, evt](lldb_private::MainLoopBase &) { - m_handler->Received(evt); + if (MessageHandler *target = Target()) + target->Received(evt); }); return llvm::Error::success(); } llvm::Error Send(const typename Proto::Req &req) override { - EXPECT_TRUE(m_handler) << "Send called before RegisterMessageHandler"; + EXPECT_TRUE(Target()) << "Send called before RegisterMessageHandler"; m_loop.AddPendingCallback([this, req](lldb_private::MainLoopBase &) { - m_handler->Received(req); + if (MessageHandler *target = Target()) + target->Received(req); }); return llvm::Error::success(); } llvm::Error Send(const typename Proto::Resp &resp) override { - EXPECT_TRUE(m_handler) << "Send called before RegisterMessageHandler"; + EXPECT_TRUE(Target()) << "Send called before RegisterMessageHandler"; m_loop.AddPendingCallback([this, resp](lldb_private::MainLoopBase &) { - m_handler->Received(resp); + if (MessageHandler *target = Target()) + target->Received(resp); }); return llvm::Error::success(); } @@ -97,8 +115,13 @@ class TestTransport final void Log(llvm::StringRef message) override {}; private: + /// The handler a sent message is delivered to: the peer's when cross-wired + /// (see createConnectedPair), otherwise this transport's own handler. + MessageHandler *Target() { return m_peer ? m_peer->m_handler : m_handler; } + lldb_private::MainLoop &m_loop; MessageHandler *m_handler = nullptr; + TestTransport *m_peer = nullptr; bool m_register_should_fail = false; }; diff --git a/llvm/benchmarks/CMakeLists.txt b/llvm/benchmarks/CMakeLists.txt index fbfc9a63e1e8c..ab15943893f5d 100644 --- a/llvm/benchmarks/CMakeLists.txt +++ b/llvm/benchmarks/CMakeLists.txt @@ -18,6 +18,7 @@ add_benchmark(PointerUnionBM PointerUnionBM.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(ImmutableSetIteratorBM ImmutableSetIteratorBM.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(RuntimeLibcallsBench RuntimeLibcalls.cpp PARTIAL_SOURCES_INTENDED) +add_benchmark(writeToOutputInParallelBench writeToOutputInParallel.cpp PARTIAL_SOURCES_INTENDED) if(NOT LLVM_TOOL_LLVM_DRIVER_BUILD) # TODO: Check if the tools are in LLVM_DISTRIBUTION_COMPONENTS with diff --git a/llvm/benchmarks/writeToOutputInParallel.cpp b/llvm/benchmarks/writeToOutputInParallel.cpp new file mode 100644 index 0000000000000..c2b29f07a3eee --- /dev/null +++ b/llvm/benchmarks/writeToOutputInParallel.cpp @@ -0,0 +1,113 @@ +//===- writeToOutputInParallel.cpp - Parallel file writing benchmark ------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "benchmark/benchmark.h" +#include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include + +using namespace llvm; + +// Benchmark parallel file writing using writeToOutput. This simulates scenarios +// where multiple threads are writing files concurrently, which is common in +// parallel compilation scenarios. The goal of this benchmark is to ensure that +// LLVM's global signal handling state updates aren't too expensive. +static void BM_WriteToOutputInParallel(benchmark::State &State) { + const int NumThreads = State.range(0); + const int FilesPerThread = State.range(1); + const int BytesPerFile = 40 * 1024; // ~40KB per file + + for (auto _ : State) { + // Create one top-level unique directory + SmallString<128> TopLevelDir; + if (sys::fs::createUniqueDirectory("writeToOutputBM", TopLevelDir)) { + State.SkipWithError("Failed to create temporary directory"); + return; + } + auto Cleanup = + llvm::scope_exit([&]() { sys::fs::remove_directories(TopLevelDir); }); + + // Create subdirectories for each thread within the top-level directory + std::vector> ThreadDirs; + for (int I = 0; I < NumThreads; ++I) { + SmallString<128> ThreadDir(TopLevelDir); + sys::path::append(ThreadDir, "thread_" + std::to_string(I)); + if (sys::fs::create_directory(ThreadDir)) { + State.SkipWithError("Failed to create thread directory"); + return; + } + ThreadDirs.push_back(ThreadDir); + } + + // Launch threads, each writing multiple files + std::vector Threads; + for (int ThreadIdx = 0; ThreadIdx < NumThreads; ++ThreadIdx) { + Threads.emplace_back([&, ThreadIdx]() { + const auto &ThreadDir = ThreadDirs[ThreadIdx]; + for (int FileIdx = 0; FileIdx < FilesPerThread; ++FileIdx) { + SmallString<128> Path(ThreadDir); + sys::path::append(Path, "file_" + std::to_string(FileIdx) + ".bin"); + + Error E = writeToOutput(Path, [=](raw_ostream &Out) -> Error { + // Write 32-bit integers up to BytesPerFile + const int NumInts = BytesPerFile / sizeof(int32_t); + for (int32_t I = 0; I < NumInts; ++I) { + Out.write(reinterpret_cast(&I), sizeof(I)); + } + return Error::success(); + }); + if (E) { + State.SkipWithError("Failed to create outputfile " + + Path.str().str()); + return; + } + } + }); + } + + // Wait for all threads to complete + for (auto &Thread : Threads) { + Thread.join(); + } + + // Cleanup happens automatically via scope_exit + } + + // Report throughput metrics + const int64_t TotalFiles = NumThreads * FilesPerThread; + const int64_t TotalBytes = TotalFiles * BytesPerFile; + + State.SetItemsProcessed(State.iterations() * TotalFiles); + State.SetBytesProcessed(State.iterations() * TotalBytes); + State.counters["threads"] = NumThreads; + State.counters["files_per_thread"] = FilesPerThread; + State.counters["total_files"] = TotalFiles; +} + +// Test various combinations of thread counts and files per thread +// These represent different parallelism scenarios: +// - Low parallelism, many files per thread (serial-like workload) +// - High parallelism, few files per thread (highly parallel workload) +// - Balanced scenarios + +BENCHMARK(BM_WriteToOutputInParallel) + ->Args({1, 1000}) // 1 thread, 1000 files + ->Args({2, 500}) // 2 threads, 500 files each + ->Args({4, 250}) // 4 threads, 250 files each + ->Args({8, 125}) // 8 threads, 125 files each + ->Args({10, 100}) // 10 threads, 100 files each + ->Args({10, 1000}) // 10 threads, 1000 files each (stress test) + ->Unit(benchmark::kMillisecond); + +BENCHMARK_MAIN(); diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in b/llvm/cmake/modules/LLVMConfig.cmake.in index 8eaf659d82c0c..300c25e7c6101 100644 --- a/llvm/cmake/modules/LLVMConfig.cmake.in +++ b/llvm/cmake/modules/LLVMConfig.cmake.in @@ -56,47 +56,52 @@ set(LLVM_ENABLE_ASSERTIONS @LLVM_ENABLE_ASSERTIONS@) set(LLVM_ENABLE_EH @LLVM_ENABLE_EH@) set(LLVM_ENABLE_FFI @LLVM_ENABLE_FFI@) +if(LLVM_ENABLE_FFI) + find_package(FFI) +endif() + set(LLVM_ENABLE_RTTI @LLVM_ENABLE_RTTI@) + +set(LLVM_ENABLE_LIBEDIT @HAVE_LIBEDIT@) +if(LLVM_ENABLE_LIBEDIT) + find_package(LibEdit) +endif() + set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@) + set(LLVM_ENABLE_UNWIND_TABLES @LLVM_ENABLE_UNWIND_TABLES@) + set(LLVM_ENABLE_ZLIB @LLVM_ENABLE_ZLIB@) +if(LLVM_ENABLE_ZLIB) + set(ZLIB_ROOT @ZLIB_ROOT@) + find_package(ZLIB) +endif() + set(LLVM_ENABLE_ZSTD @LLVM_ENABLE_ZSTD@) +if(LLVM_ENABLE_ZSTD) + find_package(zstd) +endif() + set(LLVM_ENABLE_LIBXML2 @LLVM_ENABLE_LIBXML2@) +if(LLVM_ENABLE_LIBXML2) + find_package(LibXml2) +endif() + set(LLVM_ENABLE_CURL @LLVM_ENABLE_CURL@) +if(LLVM_ENABLE_CURL) + find_package(CURL) +endif() + set(LLVM_ENABLE_HTTPLIB @LLVM_ENABLE_HTTPLIB@) +if(LLVM_ENABLE_HTTPLIB) + find_package(httplib) +endif() + set(LLVM_WITH_Z3 @LLVM_WITH_Z3@) -set(LLVM_ENABLE_DIA_SDK @LLVM_ENABLE_DIA_SDK@) -set(LLVM_ENABLE_LIBEDIT @HAVE_LIBEDIT@) -# These are host libraries that LLVM was built with. Only find them when the -# consumer can actually use them (i.e. not when cross-compiling for an -# incompatible target). -if(NOT CMAKE_CROSSCOMPILING) - if(LLVM_ENABLE_FFI) - find_package(FFI) - endif() - if(LLVM_ENABLE_LIBEDIT) - find_package(LibEdit) - endif() - if(LLVM_ENABLE_ZLIB) - set(ZLIB_ROOT @ZLIB_ROOT@) - find_package(ZLIB) - endif() - if(LLVM_ENABLE_ZSTD) - find_package(zstd) - endif() - if(LLVM_ENABLE_LIBXML2) - find_package(LibXml2) - endif() - if(LLVM_ENABLE_CURL) - find_package(CURL) - endif() - if(LLVM_ENABLE_HTTPLIB) - find_package(httplib) - endif() - if(LLVM_ENABLE_DIA_SDK) - find_package(DIASDK) - endif() +set(LLVM_ENABLE_DIA_SDK @LLVM_ENABLE_DIA_SDK@) +if(LLVM_ENABLE_DIA_SDK) + find_package(DIASDK) endif() set(LLVM_NATIVE_ARCH @LLVM_NATIVE_ARCH@) diff --git a/llvm/cmake/modules/LLVMExternalProjectUtils.cmake b/llvm/cmake/modules/LLVMExternalProjectUtils.cmake index 9567792e664e4..ee270d70a778d 100644 --- a/llvm/cmake/modules/LLVMExternalProjectUtils.cmake +++ b/llvm/cmake/modules/LLVMExternalProjectUtils.cmake @@ -84,6 +84,12 @@ function(llvm_ExternalProject_Add name source_dir) endif() endforeach() + # If CMAKE_SYSTEM_NAME is not set explicitly in the arguments passed to us, + # reflect CMake's own default. + if (NOT _cmake_system_name) + set(_cmake_system_name "${CMAKE_HOST_SYSTEM_NAME}") + endif() + if(NOT ARG_TARGET_TRIPLE) set(target_triple ${LLVM_DEFAULT_TARGET_TRIPLE}) else() @@ -92,36 +98,6 @@ function(llvm_ExternalProject_Add name source_dir) is_msvc_triple(is_msvc_target "${target_triple}") - if(ARG_USE_TOOLCHAIN AND NOT CMAKE_CROSSCOMPILING) - set(_cmake_c_compiler "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}") - set(_cmake_cxx_compiler "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}") - set(_cmake_asm_compiler "${_cmake_c_compiler}") - if(is_msvc_target) - set(_cmake_c_compiler "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}") - set(_cmake_cxx_compiler "${_cmake_c_compiler}") - set(_cmake_asm_compiler "${_cmake_c_compiler}") - endif() - else() - set(_cmake_c_compiler "${CMAKE_C_COMPILER}") - set(_cmake_cxx_compiler "${CMAKE_CXX_COMPILER}") - set(_cmake_asm_compiler "${CMAKE_C_COMPILER}") - endif() - - # If CMAKE_SYSTEM_NAME is not set explicitly in the arguments passed to us, - # derive it from the target triple if available, otherwise reflect CMake's - # own default. This ensures that cross-compilation targets get the correct - # platform files (e.g. AMDGPU targets on a Darwin host won't get macOS flags). - if (NOT _cmake_system_name) - if(ARG_TARGET_TRIPLE) - include(NormalizeTriple) - normalize_triple("${_cmake_c_compiler}" "${ARG_TARGET_TRIPLE}" _normalized_triple) - include(GetTripleCMakeSystemName) - get_triple_cmake_system_name("${_normalized_triple}" _cmake_system_name) - else() - set(_cmake_system_name "${CMAKE_HOST_SYSTEM_NAME}") - endif() - endif() - if(NOT ARG_TOOLCHAIN_TOOLS) set(ARG_TOOLCHAIN_TOOLS clang) if (ARG_ENABLE_FORTRAN) @@ -255,9 +231,15 @@ function(llvm_ExternalProject_Add name source_dir) if(ARG_USE_TOOLCHAIN AND NOT CMAKE_CROSSCOMPILING) if(CLANG_IN_TOOLCHAIN) - set(compiler_args -DCMAKE_C_COMPILER=${_cmake_c_compiler} - -DCMAKE_CXX_COMPILER=${_cmake_cxx_compiler} - -DCMAKE_ASM_COMPILER=${_cmake_asm_compiler}) + if(is_msvc_target) + set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}) + else() + set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}) + endif() endif() if(FLANG_IN_TOOLCHAIN) list(APPEND compiler_args -DCMAKE_Fortran_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/flang${CMAKE_EXECUTABLE_SUFFIX}) @@ -397,22 +379,6 @@ function(llvm_ExternalProject_Add name source_dir) list(APPEND compiler_args -DCMAKE_CXX_COMPILER_TARGET=${ARG_TARGET_TRIPLE}) list(APPEND compiler_args -DCMAKE_Fortran_COMPILER_TARGET=${ARG_TARGET_TRIPLE}) list(APPEND compiler_args -DCMAKE_ASM_COMPILER_TARGET=${ARG_TARGET_TRIPLE}) - - # Pass CMAKE_SYSTEM_NAME derived from the target triple so the sub-build - # loads the correct platform files instead of the host's. - if(NOT "${_cmake_system_name}" STREQUAL "${CMAKE_HOST_SYSTEM_NAME}") - list(APPEND compiler_args -DCMAKE_SYSTEM_NAME=${_cmake_system_name}) - endif() - - # Forward Darwin-specific variables only when targeting Darwin. - if("${_cmake_system_name}" STREQUAL "Darwin") - if(CMAKE_OSX_SYSROOT) - list(APPEND compiler_args -DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}) - endif() - if(CMAKE_OSX_DEPLOYMENT_TARGET) - list(APPEND compiler_args -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}) - endif() - endif() endif() if(CMAKE_VERBOSE_MAKEFILE) diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h index 34ba2a2cae897..86bf5aea7b23a 100644 --- a/llvm/include/llvm/CodeGen/Passes.h +++ b/llvm/include/llvm/CodeGen/Passes.h @@ -279,6 +279,13 @@ LLVM_ABI extern char &PostRASchedulerID; /// branches. LLVM_ABI extern char &BranchFolderPassID; +/// createBranchFolder - Create the BranchFolder pass, optionally disabling the +/// common-code hoisting and/or basic-block reordering sub-phases. Default +/// enables both (full BranchFolding behavior). +LLVM_ABI FunctionPass * +createBranchFolder(bool EnableCommonHoist = true, + bool EnableBasicBlockReordering = true); + /// BranchRelaxation - This pass replaces branches that need to jump further /// than is supported by a branch instruction. LLVM_ABI extern char &BranchRelaxationPassID; diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h index 9787ef4c916a9..289d962e993b8 100644 --- a/llvm/include/llvm/MC/MCGOFFAttributes.h +++ b/llvm/include/llvm/MC/MCGOFFAttributes.h @@ -57,7 +57,6 @@ struct EDAttr { GOFF::ESDBindingAlgorithm BindAlgorithm = GOFF::ESD_BA_Concatenate; GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial; GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0; - GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword; uint8_t FillByteValue = 0; }; diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h index 288f9038bb65e..6351a1e3dc933 100644 --- a/llvm/include/llvm/MC/MCSectionGOFF.h +++ b/llvm/include/llvm/MC/MCSectionGOFF.h @@ -19,8 +19,6 @@ #include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCSection.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" namespace llvm { @@ -98,6 +96,17 @@ class LLVM_ABI MCSectionGOFF final : public MCSection { assert(isED() && "Not a ED section"); return EDAttributes; } + + // Returns the ESD alignment value for the ED section, computed from the + // MCSection alignment. Only defined for ED sections. + GOFF::ESDAlignment getEDAlignment() const { + assert(isED() && "Not a ED section"); + uint8_t Log = Log2(getAlign()); + if (Log > GOFF::ESD_ALIGN_4Kpage) + reportFatalUsageError("Unsupported alignment"); + return static_cast(Log); + } + GOFF::PRAttr getPRAttributes() const { assert(isPR() && "Not a PR section"); return PRAttributes; diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h index e4f467c45c66a..b9eabcd661549 100644 --- a/llvm/include/llvm/ProfileData/SampleProf.h +++ b/llvm/include/llvm/ProfileData/SampleProf.h @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -386,7 +385,7 @@ class SampleRecord { } }; - using SortedCallTargetSet = std::set; + using SortedCallTargetSet = SmallVector; using CallTargetMap = DenseMap; SampleRecord() = default; @@ -443,7 +442,7 @@ class SampleRecord { uint64_t getSamples() const { return NumSamples; } const CallTargetMap &getCallTargets() const { return CallTargets; } - const SortedCallTargetSet getSortedCallTargets() const { + SortedCallTargetSet getSortedCallTargets() const { return sortCallTargets(CallTargets); } @@ -455,12 +454,9 @@ class SampleRecord { } /// Sort call targets in descending order of call frequency. - static const SortedCallTargetSet - sortCallTargets(const CallTargetMap &Targets) { - SortedCallTargetSet SortedTargets; - for (const auto &[Target, Frequency] : Targets) { - SortedTargets.emplace(Target, Frequency); - } + static SortedCallTargetSet sortCallTargets(const CallTargetMap &Targets) { + auto SortedTargets = llvm::to_vector_of(Targets); + llvm::sort(SortedTargets, CallTargetComparator()); return SortedTargets; } diff --git a/llvm/include/llvm/ProfileData/SampleProfWriter.h b/llvm/include/llvm/ProfileData/SampleProfWriter.h index b7a9382f08bb7..8756c038ff17c 100644 --- a/llvm/include/llvm/ProfileData/SampleProfWriter.h +++ b/llvm/include/llvm/ProfileData/SampleProfWriter.h @@ -22,7 +22,6 @@ #include "llvm/Support/raw_ostream.h" #include #include -#include #include namespace llvm { @@ -224,8 +223,6 @@ class LLVM_ABI SampleProfileWriterBinary : public SampleProfileWriter { virtual std::error_code writeContextIdx(const SampleContext &Context); std::error_code writeNameIdx(FunctionId FName); std::error_code writeBody(const FunctionSamples &S); - inline void stablizeNameTable(MapVector &NameTable, - std::set &V); MapVector NameTable; diff --git a/llvm/include/llvm/TargetParser/PPCTargetParser.h b/llvm/include/llvm/TargetParser/PPCTargetParser.h index d3d44afb5f544..9f39551377f70 100644 --- a/llvm/include/llvm/TargetParser/PPCTargetParser.h +++ b/llvm/include/llvm/TargetParser/PPCTargetParser.h @@ -43,6 +43,7 @@ LLVM_ABI StringRef normalizeCPUName(StringRef CPUName); LLVM_ABI std::optional> getPPCDefaultTargetFeatures(const Triple &T, StringRef CPUName); +LLVM_ABI bool isValidFeatureName(StringRef Name); } // namespace PPC } // namespace llvm diff --git a/llvm/include/llvm/TargetParser/TargetParser.h b/llvm/include/llvm/TargetParser/TargetParser.h index b65ff37dfc958..2346c5f407219 100644 --- a/llvm/include/llvm/TargetParser/TargetParser.h +++ b/llvm/include/llvm/TargetParser/TargetParser.h @@ -27,6 +27,9 @@ struct BasicSubtargetFeatureKV { const char *Key; ///< K-V key string unsigned Value; ///< K-V integer value FeatureBitArray Implies; ///< K-V bit mask + + /// Compare routine for std::lower_bound + bool operator<(StringRef S) const { return StringRef(Key) < S; } }; /// Used to provide key value pairs for feature and CPU bit flags. diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h index b1fa6ed7742e8..90a74f58e85ef 100644 --- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h +++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h @@ -335,8 +335,8 @@ class LegalityAnalysis { public: LegalityAnalysis(AAResults &AA, ScalarEvolution &SE, const DataLayout &DL, - Context &Ctx, InstrMaps &IMaps) - : Sched(AA, Ctx), SE(SE), DL(DL), IMaps(IMaps) {} + Context &Ctx, InstrMaps &IMaps, SchedDirection Dir) + : Sched(AA, Ctx, Dir), SE(SE), DL(DL), IMaps(IMaps) {} /// A LegalityResult factory. template ResultT &createLegalityResult(ArgsT &&...Args) { diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h index 86ab5fb8b464b..f406560b246a6 100644 --- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h +++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h @@ -230,7 +230,8 @@ class Scheduler { SchedDirection Dir = SchedDirection::BottomUp; public: - Scheduler(AAResults &AA, Context &Ctx) : DAG(AA, Ctx), Ctx(Ctx) { + Scheduler(AAResults &AA, Context &Ctx, SchedDirection Dir) + : DAG(AA, Ctx), Ctx(Ctx), Dir(Dir) { // NOTE: The scheduler's callback depends on the DAG's callback running // before it and updating the DAG accordingly. CreateInstrCB = Ctx.registerCreateInstrCallback( @@ -240,12 +241,6 @@ class Scheduler { if (CreateInstrCB) Ctx.unregisterCreateInstrCallback(*CreateInstrCB); } - void setDirection(SchedDirection NewDir) { - assert(Bndls.empty() && DAG.empty() && ReadyList.empty() && - !ScheduleTopItOpt && ScheduledBB == nullptr && - "We can't change the direction during scheduling!"); - Dir = NewDir; - } /// Tries to build a schedule that includes all of \p Instrs scheduled at the /// same scheduling cycle. This essentially checks that there are no /// dependencies among \p Instrs. This function may involve scheduling diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp index 2fdd766102a7f..79fd1e833a4c5 100644 --- a/llvm/lib/CodeGen/BranchFolding.cpp +++ b/llvm/lib/CodeGen/BranchFolding.cpp @@ -78,6 +78,20 @@ static cl::opt FlagEnableTailMerge("enable-tail-merge", cl::init(cl::boolOrDefault::BOU_UNSET), cl::Hidden); +// Override the common-code hoisting sub-phase of BranchFolding. Unset by +// default, in which case the value configured by the caller is used. +static cl::opt FlagEnableHoistCommonCode( + "branch-folder-hoist-common-code", cl::init(cl::boolOrDefault::BOU_UNSET), + cl::Hidden, + cl::desc("Override common-code hoisting in the BranchFolding pass")); + +// Override the basic-block reordering sub-phase of BranchFolding. Unset by +// default, in which case the value configured by the caller is used. +static cl::opt FlagEnableBlockReordering( + "branch-folder-reorder-blocks", cl::init(cl::boolOrDefault::BOU_UNSET), + cl::Hidden, + cl::desc("Override basic-block reordering in the BranchFolding pass")); + // Throttle for huge numbers of predecessors (compile speed problems) static cl::opt TailMergeThreshold("tail-merge-threshold", @@ -94,10 +108,16 @@ namespace { /// BranchFolderPass - Wrap branch folder in a machine function pass. class BranchFolderLegacy : public MachineFunctionPass { + bool EnableCommonHoist; + bool EnableBasicBlockReordering; + public: static char ID; - explicit BranchFolderLegacy() : MachineFunctionPass(ID) {} + explicit BranchFolderLegacy(bool EnableCommonHoist = true, + bool EnableBasicBlockReordering = true) + : MachineFunctionPass(ID), EnableCommonHoist(EnableCommonHoist), + EnableBasicBlockReordering(EnableBasicBlockReordering) {} bool runOnMachineFunction(MachineFunction &MF) override; @@ -141,6 +161,7 @@ PreservedAnalyses BranchFolderPass::run(MachineFunction &MF, MBFIWrapper MBBFreqInfo(MBFI); BranchFolder Folder(EnableTailMerge, /*CommonHoist=*/true, MBBFreqInfo, MBPI, PSI); + Folder.setBasicBlockReordering(true); if (Folder.OptimizeFunction(MF, MF.getSubtarget().getInstrInfo(), MF.getSubtarget().getRegisterInfo())) return getMachineFunctionPassPreservedAnalyses(); @@ -160,9 +181,10 @@ bool BranchFolderLegacy::runOnMachineFunction(MachineFunction &MF) { MBFIWrapper MBBFreqInfo( getAnalysis().getMBFI()); BranchFolder Folder( - EnableTailMerge, /*CommonHoist=*/true, MBBFreqInfo, + EnableTailMerge, EnableCommonHoist, MBBFreqInfo, getAnalysis().getMBPI(), &getAnalysis().getPSI()); + Folder.setBasicBlockReordering(EnableBasicBlockReordering); return Folder.OptimizeFunction(MF, MF.getSubtarget().getInstrInfo(), MF.getSubtarget().getRegisterInfo()); } @@ -171,8 +193,9 @@ BranchFolder::BranchFolder(bool DefaultEnableTailMerge, bool CommonHoist, MBFIWrapper &FreqInfo, const MachineBranchProbabilityInfo &ProbInfo, ProfileSummaryInfo *PSI, unsigned MinTailLength) - : EnableHoistCommonCode(CommonHoist), MinCommonTailLength(MinTailLength), - MBBFreqInfo(FreqInfo), MBPI(ProbInfo), PSI(PSI) { + : EnableHoistCommonCode(CommonHoist), EnableBasicBlockReordering(true), + MinCommonTailLength(MinTailLength), MBBFreqInfo(FreqInfo), MBPI(ProbInfo), + PSI(PSI) { switch (FlagEnableTailMerge) { case cl::boolOrDefault::BOU_UNSET: EnableTailMerge = DefaultEnableTailMerge; @@ -235,6 +258,16 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF, if (!UpdateLiveIns) MRI.invalidateLiveness(); + // Command-line flags take final precedence over the caller-configured values, + // letting individual BranchFolding sub-phases be toggled (for tests and for + // targets that only want a safe subset of the optimization). + if (FlagEnableHoistCommonCode != cl::boolOrDefault::BOU_UNSET) + EnableHoistCommonCode = + FlagEnableHoistCommonCode == cl::boolOrDefault::BOU_TRUE; + if (FlagEnableBlockReordering != cl::boolOrDefault::BOU_UNSET) + EnableBasicBlockReordering = + FlagEnableBlockReordering == cl::boolOrDefault::BOU_TRUE; + bool MadeChange = false; // Recalculate EH scope membership. @@ -1526,8 +1559,8 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { // We consider it more likely that execution will stay in the function (e.g. // due to loops) than it is to exit it. This asserts in loops etc, moving // the assert condition out of the loop body. - if (MBB->succ_empty() && !PriorCond.empty() && !PriorFBB && - MachineFunction::iterator(PriorTBB) == FallThrough && + if (EnableBasicBlockReordering && MBB->succ_empty() && !PriorCond.empty() && + !PriorFBB && MachineFunction::iterator(PriorTBB) == FallThrough && !MBB->canFallThrough()) { bool DoTransform = true; @@ -1723,7 +1756,7 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { // If the prior block doesn't fall through into this block, and if this // block doesn't fall through into some other block, see if we can find a // place to move this block where a fall-through will happen. - if (!PrevBB.canFallThrough()) { + if (EnableBasicBlockReordering && !PrevBB.canFallThrough()) { // Now we know that there was no fall-through into this block, check to // see if it has a fall-through into its successor. bool CurFallsThru = MBB->canFallThrough(); @@ -2182,3 +2215,8 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) { ++NumHoist; return true; } + +FunctionPass *llvm::createBranchFolder(bool EnableCommonHoist, + bool EnableBasicBlockReordering) { + return new BranchFolderLegacy(EnableCommonHoist, EnableBasicBlockReordering); +} diff --git a/llvm/lib/CodeGen/BranchFolding.h b/llvm/lib/CodeGen/BranchFolding.h index ff2bbe06c0488..f57211a34b0bc 100644 --- a/llvm/lib/CodeGen/BranchFolding.h +++ b/llvm/lib/CodeGen/BranchFolding.h @@ -46,6 +46,13 @@ class TargetRegisterInfo; MachineLoopInfo *mli = nullptr, bool AfterPlacement = false); + /// Enable or disable the basic-block reordering sub-phase of branch + /// optimization. Enabled by default; targets sensitive to block layout + /// (e.g. those with structured-CFG register allocation) can disable it. + void setBasicBlockReordering(bool Enable) { + EnableBasicBlockReordering = Enable; + } + private: class MergePotentialsElt { unsigned Hash; @@ -119,6 +126,7 @@ class TargetRegisterInfo; bool AfterBlockPlacement = false; bool EnableTailMerge = false; bool EnableHoistCommonCode = false; + bool EnableBasicBlockReordering = false; bool UpdateLiveIns = false; unsigned MinCommonTailLength; const TargetInstrInfo *TII = nullptr; diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 97e64230b73d9..c66226258c87e 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2882,7 +2882,6 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) { const Function &Fn = MF->getFunction(); Fn.getContext().diagnose( DiagnosticInfoUnsupportedTargetIntrinsic(Fn, ID, CI.getDebugLoc())); - return false; } if (translateKnownIntrinsic(CI, ID, MIRBuilder)) @@ -2902,7 +2901,6 @@ bool IRTranslator::translateIntrinsic( const Function &F = MF->getFunction(); F.getContext().diagnose( DiagnosticInfoUnsupportedTargetIntrinsic(F, ID, CB.getDebugLoc())); - return false; } ArrayRef ResultRegs; diff --git a/llvm/lib/CodeGen/ImplicitNullChecks.cpp b/llvm/lib/CodeGen/ImplicitNullChecks.cpp index c0f5bc81c9cf0..d06116a112c57 100644 --- a/llvm/lib/CodeGen/ImplicitNullChecks.cpp +++ b/llvm/lib/CodeGen/ImplicitNullChecks.cpp @@ -703,7 +703,6 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks( /// faults. The FAULTING instruction is inserted at the end of MBB. MachineInstr *ImplicitNullChecks::insertFaultingInstr( MachineInstr *MI, MachineBasicBlock *MBB, MachineBasicBlock *HandlerMBB) { - DebugLoc DL; unsigned NumDefs = MI->getDesc().getNumDefs(); assert(NumDefs <= 1 && "other cases unhandled!"); @@ -720,7 +719,8 @@ MachineInstr *ImplicitNullChecks::insertFaultingInstr( else FK = FaultMaps::FaultingStore; - auto MIB = BuildMI(MBB, DL, TII->get(TargetOpcode::FAULTING_OP), DefReg) + auto MIB = BuildMI(MBB, MI->getDebugLoc(), + TII->get(TargetOpcode::FAULTING_OP), DefReg) .addImm(FK) .addMBB(HandlerMBB) .addImm(MI->getOpcode()); diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 54a77524add94..43c7e89113b26 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1278,8 +1278,11 @@ void PEIImpl::insertZeroCallUsedRegs(MachineFunction &MF) { // Want only registers used for arguments. if (OnlyArg) { if (OnlyUsed) { - if (!LiveIns[Reg.id()]) - continue; + for (MCRegister LiveReg : LiveIns.set_bits()) { + if (TRI.regsOverlap(Reg, LiveReg)) + RegsToZero.set(LiveReg); + } + continue; } else if (!TRI.isArgumentRegister(MF, Reg)) { continue; } diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index f983c3205f927..174e7b088ca4b 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2865,9 +2865,9 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA( SectionKind::getMetadata(), GOFF::CLASS_WSA, GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Fullword, 0}, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, 0}, static_cast(TextSection)->getParent()); + WSA->setAlignment(Align(4)); // Fullword return getContext().getGOFFSection(SectionKind::getData(), Name, GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink, @@ -2893,9 +2893,6 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( Alignment = F->getAlign(); else if (auto *V = dyn_cast(GO)) Alignment = V->getAlign(); - GOFF::ESDAlignment Align = - Alignment ? static_cast(Log2(*Alignment)) - : GOFF::ESD_ALIGN_Doubleword; MCSectionGOFF *SD = getContext().getGOFFSection( SectionKind::getMetadata(), Symbol->getName(), GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope}); @@ -2903,8 +2900,9 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( SectionKind::getMetadata(), GOFF::CLASS_WSA, GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align, 0}, + GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, 0}, SD); + ED->setAlignment(Alignment.value_or(llvm::Align(8))); return getContext().getGOFFSection(Kind, Symbol->getName(), GOFF::PRAttr{false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink, diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp index eae1e11a6d39f..58de4e91570df 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp @@ -58,12 +58,11 @@ void TypeUnit::createDIETree(BumpPtrAllocator &Allocator) { uint64_t OutOffset = getDebugInfoHeaderSize(); UnitDIE->setOffset(OutOffset); - SmallString<200> ProducerString; - ProducerString += "llvm DWARFLinkerParallel library version "; + const char *ProducerString = + "llvm DWARFLinkerParallel library version " LLVM_VERSION_STRING; DebugInfoSection.notePatchWithOffsetUpdate( - DebugStrPatch{ - {OutOffset}, - GlobalData.getStringPool().insert(ProducerString.str()).first}, + DebugStrPatch{{OutOffset}, + GlobalData.getStringPool().insert(ProducerString).first}, PatchesOffsets); OutOffset += DIETreeGenerator .addStringPlaceholderAttribute(dwarf::DW_AT_producer, diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp index eb144275da589..5e95b8c73b482 100644 --- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp @@ -70,6 +70,7 @@ IRMaterializationUnit::IRMaterializationUnit( auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str()); SymbolFlags[EmuTLST] = Flags; + SymbolToDefinition[EmuTLST] = &GV; } continue; } diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index f47bfdee42c62..3af4851d39d94 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -457,7 +457,7 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex, if (ESize) { int64_t Res; if (!ESize->evaluateKnownAbsolute(Res, Asm)) - report_fatal_error("Size expression must be absolute."); + report_fatal_error("size expression must be absolute"); Size = Res; } diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp index 4d23746775df1..ab497ac38b90e 100644 --- a/llvm/lib/MC/GOFFObjectWriter.cpp +++ b/llvm/lib/MC/GOFFObjectWriter.cpp @@ -229,7 +229,7 @@ class GOFFSymbol { } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, - const GOFF::EDAttr &Attr) + const GOFF::EDAttr &Attr, GOFF::ESDAlignment Alignment) : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), SymbolType(GOFF::ESD_ST_ElementDefinition) { this->NameSpace = Attr.NameSpace; @@ -243,7 +243,7 @@ class GOFFSymbol { BehavAttrs.setTextStyle(Attr.TextStyle); BehavAttrs.setBindingAlgorithm(Attr.BindAlgorithm); BehavAttrs.setLoadingBehavior(Attr.LoadBehavior); - BehavAttrs.setAlignment(Attr.Alignment); + BehavAttrs.setAlignment(Alignment); } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, @@ -259,14 +259,15 @@ class GOFFSymbol { } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, - const GOFF::EDAttr &EDAttr, const GOFF::PRAttr &Attr) + const GOFF::EDAttr &EDAttr, GOFF::ESDAlignment Alignment, + const GOFF::PRAttr &Attr) : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), SymbolType(GOFF::ESD_ST_PartReference), NameSpace(EDAttr.NameSpace) { SymbolFlags.setRenameable(Attr.IsRenamable); BehavAttrs.setExecutable(Attr.Executable); BehavAttrs.setLinkageType(Attr.Linkage); BehavAttrs.setBindingScope(Attr.BindingScope); - BehavAttrs.setAlignment(EDAttr.Alignment); + BehavAttrs.setAlignment(Alignment); } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, @@ -323,7 +324,8 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) { if (Section.isED()) { GOFFSymbol ED(Section.getExternalName(), Section.getOrdinal(), - Section.getParent()->getOrdinal(), Section.getEDAttributes()); + Section.getParent()->getOrdinal(), Section.getEDAttributes(), + Section.getEDAlignment()); ED.SectionLength = Asm.getSectionAddressSize(Section); writeSymbol(ED); } @@ -332,7 +334,7 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) { MCSectionGOFF *Parent = Section.getParent(); GOFFSymbol PR(Section.getExternalName(), Section.getOrdinal(), Parent->getOrdinal(), Parent->getEDAttributes(), - Section.getPRAttributes()); + Parent->getEDAlignment(), Section.getPRAttributes()); PR.SectionLength = Asm.getSectionAddressSize(Section); if (Section.requiresNonZeroLength()) { // We cannot have a zero-length section for data. If we do, @@ -364,7 +366,7 @@ void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) { if (Symbol.getCodeData() == GOFF::ESD_EXE_DATA) { MCSectionGOFF *ED = Symbol.getADA()->getParent(); GOFFSymbol PR(Symbol.getExternalName(), Symbol.getIndex(), ED->getOrdinal(), - ED->getEDAttributes(), + ED->getEDAttributes(), ED->getEDAlignment(), GOFF::PRAttr{/*IsRenamable*/ false, Symbol.getCodeData(), Symbol.getLinkage(), Symbol.getBindingScope(), 0}); diff --git a/llvm/lib/MC/MCAsmInfoGOFF.cpp b/llvm/lib/MC/MCAsmInfoGOFF.cpp index 97063099597da..c644e599bfb26 100644 --- a/llvm/lib/MC/MCAsmInfoGOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoGOFF.cpp @@ -140,10 +140,10 @@ void MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section, case GOFF::ESD_ST_ElementDefinition: { printSwitchToSection(*Sec.getParent(), Subsection, T, OS); if (!Sec.Emitted) { - emitCATTR(OS, Sec.getName(), Sec.EDAttributes.Rmode, - Sec.EDAttributes.Alignment, Sec.EDAttributes.LoadBehavior, - GOFF::ESD_EXE_Unspecified, Sec.EDAttributes.IsReadOnly, 0, - Sec.EDAttributes.FillByteValue, StringRef()); + emitCATTR(OS, Sec.getName(), Sec.EDAttributes.Rmode, Sec.getEDAlignment(), + Sec.EDAttributes.LoadBehavior, GOFF::ESD_EXE_Unspecified, + Sec.EDAttributes.IsReadOnly, 0, Sec.EDAttributes.FillByteValue, + StringRef()); if (auto *BeginSym = static_cast(Sec.getBeginSymbol())) { if (BeginSym->getADA()) emitXATTR(OS, BeginSym->getName(), BeginSym->getADA(), @@ -161,7 +161,7 @@ void MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section, printSwitchToSection(*ED->getParent(), Subsection, T, OS); if (!Sec.Emitted) { emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode, - ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior, + ED->getEDAlignment(), ED->EDAttributes.LoadBehavior, Sec.PRAttributes.Executable, ED->EDAttributes.IsReadOnly, Sec.PRAttributes.SortKey, ED->EDAttributes.FillByteValue, Sec.getName()); diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index b4b660c104868..2ac01cf4b84de 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -587,9 +587,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { SectionKind::getMetadata(), GOFF::CLASS_WSA, GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1, - GOFF::ESD_ALIGN_Quadword, 0}, + GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1, 0}, RootSDSection); + ADAEDSection->setAlignment(Align(16)); // Quadword ADASection = Ctx->getGOFFSection(SectionKind::getData(), "#S", GOFF::PRAttr{false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink, @@ -600,17 +600,17 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { SectionKind::getText(), GOFF::CLASS_CODE, GOFF::EDAttr{true, GOFF::ESD_RMODE_64, GOFF::ESD_NS_NormalName, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate, - GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword, 0}, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, 0}, RootSDSection); + TextSection->setAlignment(Align(8)); // Doubleword MCSectionGOFF *PPA2ListEDSection = Ctx->getGOFFSection( SectionKind::getMetadata(), GOFF::CLASS_PPA2, GOFF::EDAttr{true, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword, 0}, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, 0}, RootSDSection); + PPA2ListEDSection->setAlignment(Align(8)); // Doubleword PPA2ListSection = Ctx->getGOFFSection(SectionKind::getData(), ".&ppa2", GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_OS, @@ -621,9 +621,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { SectionKind::getData(), "B_IDRL", GOFF::EDAttr{true, GOFF::ESD_RMODE_64, GOFF::ESD_NS_NormalName, GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate, - GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword, 0}, + GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, 0}, RootSDSection); + IDRLSection->setAlignment(Align(8)); // Doubleword // Debug Info Sections. The ED name is the same used by the XL compiler. auto InitDebugSection = [this, @@ -633,9 +633,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { SectionKind::getMetadata(), EDName, GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate, - GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword, 0}, + GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, 0}, RootSDSection); + ED->setAlignment(Align(8)); // Doubleword // At least for llc, this function is called twice! (See function // compileModule() in llc.cpp). Since the context is not cleared, the // already allocated section is returned above. We only add the begin symbol diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index b42155d18bf0a..e274d886c22d8 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -1060,7 +1060,7 @@ uint64_t MachObjectWriter::writeObject() { if (Data.End) End = getSymbolAddress(*Data.End); else - report_fatal_error("Data region not terminated"); + report_fatal_error("data region not terminated"); LLVM_DEBUG(dbgs() << "data in code region-- kind: " << Data.Kind << " start: " << Start << "(" << Data.Start->getName() diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 0231206ea1e79..08458f8345209 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -396,7 +396,7 @@ relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { const coff_section *Sec = toSec(Ref); const coff_relocation *begin = getFirstReloc(Sec, Data, base()); if (begin && Sec->VirtualAddress != 0) - report_fatal_error("Sections with relocations should have an address of 0"); + report_fatal_error("sections with relocations should have an address of 0"); DataRefImpl Ret; Ret.p = reinterpret_cast(begin); return relocation_iterator(RelocationRef(Ret, this)); diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp index dd051e265284d..62bdf5343a2f0 100644 --- a/llvm/lib/ProfileData/SampleProfWriter.cpp +++ b/llvm/lib/ProfileData/SampleProfWriter.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -347,21 +346,34 @@ std::error_code SampleProfileWriterExtBinaryBase::writeFuncMetadata( return sampleprof_error::success; } +template +static SmallVector *, 0> +stabilizeTable(MapVector &Table) { + SmallVector *, 0> Entries( + llvm::make_pointer_range(Table)); + + llvm::sort(Entries, + [](const auto *L, const auto *R) { return L->first < R->first; }); + + for (const auto &[I, Entry] : llvm::enumerate(Entries)) + Entry->second = I; + + return Entries; +} + std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() { if (!UseMD5) return SampleProfileWriterBinary::writeNameTable(); auto &OS = *OutputStream; - std::set V; - stablizeNameTable(NameTable, V); // Write out the MD5 name table. We wrote unencoded MD5 so reader can // retrieve the name using the name index without having to read the // whole name table. encodeULEB128(NameTable.size(), OS); support::endian::Writer Writer(OS, llvm::endianness::little); - for (auto N : V) - Writer.write(N.getHashCode()); + for (const auto *Entry : stabilizeTable(NameTable)) + Writer.write(Entry->first.getHashCode()); return sampleprof_error::success; } @@ -391,21 +403,11 @@ std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection( } std::error_code SampleProfileWriterExtBinaryBase::writeCSNameTableSection() { - // Sort the names to make CSNameTable deterministic. - std::set OrderedContexts; - for (const auto &I : CSNameTable) - OrderedContexts.insert(I.first); - assert(OrderedContexts.size() == CSNameTable.size() && - "Unmatched ordered and unordered contexts"); - uint64_t I = 0; - for (auto &Context : OrderedContexts) - CSNameTable[Context] = I++; - auto &OS = *OutputStream; - encodeULEB128(OrderedContexts.size(), OS); + encodeULEB128(CSNameTable.size(), OS); support::endian::Writer Writer(OS, llvm::endianness::little); - for (auto Context : OrderedContexts) { - auto Frames = Context.getContextFrames(); + for (const auto *Entry : stabilizeTable(CSNameTable)) { + auto Frames = Entry->first.getContextFrames(); encodeULEB128(Frames.size(), OS); for (auto &Callsite : Frames) { if (std::error_code EC = writeNameIdx(Callsite.Func)) @@ -731,25 +733,13 @@ void SampleProfileWriterExtBinaryBase::addContext( } } -void SampleProfileWriterBinary::stablizeNameTable( - MapVector &NameTable, std::set &V) { - // Sort the names to make NameTable deterministic. - for (const auto &I : NameTable) - V.insert(I.first); - int i = 0; - for (const FunctionId &N : V) - NameTable[N] = i++; -} - std::error_code SampleProfileWriterBinary::writeNameTable() { auto &OS = *OutputStream; - std::set V; - stablizeNameTable(NameTable, V); // Write out the name table. encodeULEB128(NameTable.size(), OS); - for (auto N : V) { - OS << N; + for (const auto *Entry : stabilizeTable(NameTable)) { + OS << Entry->first; encodeULEB128(0, OS); } return sampleprof_error::success; diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index 981d53985e4bc..772fa37b004ac 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -98,6 +98,10 @@ static std::atomic OneShotPipeSignalFunction = nullptr; namespace { +/// Sentinel stored in a node after the signal handler has removed the file; +/// not a valid path, never freed. +static char InvalidPathSentinel[] = "\01\02\03\04"; + /// Signal-safe removal of files. /// Inserting and erasing from the list isn't signal-safe, but removal of files /// themselves is signal-safe. Memory is freed when the head is freed, deletion @@ -107,8 +111,8 @@ class FileToRemoveList { std::atomic Next = nullptr; FileToRemoveList() = default; - // Not signal-safe. - FileToRemoveList(const std::string &str) : Filename(strdup(str.c_str())) {} + // Takes ownership of \p filename. + FileToRemoveList(char *filename) : Filename(filename) {} public: // Not signal-safe. @@ -116,19 +120,35 @@ public: if (FileToRemoveList *N = Next.exchange(nullptr)) delete N; if (char *F = Filename.exchange(nullptr)) - free(F); + if (F != InvalidPathSentinel) + free(F); } // Not signal-safe. static void insert(std::atomic &Head, const std::string &Filename) { - // Insert the new file at the end of the list. - FileToRemoveList *NewHead = new FileToRemoveList(Filename); + // Reuse a node with a null filename (left behind by erase) if one exists. + // There are two cases where Filename can be special: + // - nullptr: a node left behind by a previous file that we had to remove + // - InvalidPathSentinel: a node whose file is actively being removed by a + // signal handler right now, in which case it's OK if this file doesn't + // get removed. + char *NewFilename = strdup(Filename.c_str()); std::atomic *InsertionPoint = &Head; - FileToRemoveList *OldHead = nullptr; - while (!InsertionPoint->compare_exchange_strong(OldHead, NewHead)) { - InsertionPoint = &OldHead->Next; - OldHead = nullptr; + for (FileToRemoveList *Current = Head.load(); Current; + Current = Current->Next.load()) { + char *NullFilename = nullptr; + if (Current->Filename.compare_exchange_strong(NullFilename, NewFilename)) + return; // Reused a slot. + InsertionPoint = &Current->Next; + } + + // Append the new node at the end; on CAS failure, advance to the new tail. + FileToRemoveList *NewNode = new FileToRemoveList(NewFilename); + FileToRemoveList *OldNext = nullptr; + while (!InsertionPoint->compare_exchange_strong(OldNext, NewNode)) { + InsertionPoint = &OldNext->Next; + OldNext = nullptr; } } @@ -145,11 +165,15 @@ public: if (char *OldFilename = Current->Filename.load()) { if (OldFilename != Filename) continue; - // Leave an empty filename. - OldFilename = Current->Filename.exchange(nullptr); - // The filename might have become null between the time we - // compared it and we exchanged it. - if (OldFilename) + // Leave an empty filename. Use CAS to avoid racing with the signal + // handler (which can't take the writer lock); only clear and free + // if we still own the pointer. + char *Expected = OldFilename; + while (!Current->Filename.compare_exchange_strong(Expected, nullptr)) { + if (Expected == nullptr || Expected == InvalidPathSentinel) + break; + } + if (Expected == OldFilename) free(OldFilename); } } @@ -175,21 +199,23 @@ public: // Signal-safe. static void removeAllFiles(std::atomic &Head) { - // If cleanup were to occur while we're removing files we'd have a bad time. - // Make sure we're OK by preventing cleanup from doing anything while we're - // removing files. If cleanup races with us and we win we'll have a leak, - // but we won't crash. + // This signal-safe code cannot acquire the writer lock, and needs to defend + // against racing writes from the `erase` method above. FileToRemoveList *OldHead = Head.exchange(nullptr); for (FileToRemoveList *currentFile = OldHead; currentFile; currentFile = currentFile->Next.load()) { - // If erasing was occuring while we're trying to remove files we'd look - // at free'd data. Take away the path and put it back when done. - if (char *path = currentFile->Filename.exchange(nullptr)) { - removeFile(path); - - // We're done removing the file, erasing can safely proceed. - currentFile->Filename.exchange(path); + // Take exclusive ownership by swapping in the sentinel (signal-safe: no + // allocation or free). Then put the path back so we don't leak. + char *Path = currentFile->Filename.exchange(InvalidPathSentinel); + if (!Path) { + // Restore an empty slot so future insertions can reuse it. + currentFile->Filename.exchange(nullptr); + } else if (Path != InvalidPathSentinel) { + removeFile(Path); + // Add the path back to the list to create a global root referencing the + // heap allocation, which will pacify leak checkers that run at exit. + currentFile->Filename.exchange(Path); } } diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp index caca744fd4303..9e1a0960617a5 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -2179,6 +2179,32 @@ static std::optional instCombineXorSVECmpCC(InstCombiner &IC, return &II; } +// zext(cmpne(ptrue, %v, 0)) +// -> umin(%pg, %v, 1) +static std::optional instCombineZExtSVECmpNE(InstCombiner &IC, + IntrinsicInst &II) { + if (!isAllActivePredicate(II.getOperand(0)) || + !match(II.getOperand(2), m_Zero())) + return std::nullopt; + + for (auto *U : II.users()) { + if (match(U, m_ZExt(m_Specific(&II)))) { + auto *User = cast(U); + Type *Ty = II.getOperand(1)->getType(); + if (User->getType() != Ty) + continue; + IC.Builder.SetInsertPoint(User); + Value *UMin = IC.Builder.CreateIntrinsic( + Intrinsic::aarch64_sve_umin, Ty, + {II.getOperand(0), II.getOperand(1), ConstantInt::get(Ty, 1)}); + IC.replaceInstUsesWith(*User, UMin); + IC.eraseInstFromFunction(*User); + return &II; + } + } + return std::nullopt; +} + static std::optional instCombineSVECmpNE(InstCombiner &IC, IntrinsicInst &II) { LLVMContext &Ctx = II.getContext(); @@ -2186,6 +2212,9 @@ static std::optional instCombineSVECmpNE(InstCombiner &IC, if (auto Res = instCombineXorSVECmpCC(IC, II)) return Res; + if (auto Res = instCombineZExtSVECmpNE(IC, II)) + return Res; + if (!isAllActivePredicate(II.getArgOperand(0))) return std::nullopt; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp index 197b5657233ab..df7e80d62e065 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp @@ -771,11 +771,10 @@ bool PipelineSolver::solveExact() { int AddedCost = 0; std::list> AddedEdges; auto &SyncPipeline = CurrPipeline[CurrSyncGroupIdx]; - SchedGroup *Match; - for (auto &SG : SyncPipeline) { - if (SG.getSGID() == CandSGID) - Match = &SG; - } + SchedGroup *Match = llvm::find_if(SyncPipeline, [CandSGID](SchedGroup &SG) { + return SG.getSGID() == CandSGID; + }); + assert(Match); if (Match->isFull()) continue; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp index 7330f3b13f3cb..97004dd6f743a 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -1722,7 +1722,7 @@ bool AMDGPUDAGToDAGISel::SelectMUBUFScratchOffen(SDNode *Parent, AMDGPU::getNullPointerValue(AMDGPUAS::PRIVATE_ADDRESS); // Don't fold null pointer. if (Imm != NullPtr) { - const uint32_t MaxOffset = SIInstrInfo::getMaxMUBUFImmOffset(*Subtarget); + const int64_t MaxOffset = SIInstrInfo::getMaxMUBUFImmOffset(*Subtarget); SDValue HighBits = CurDAG->getTargetConstant(Imm & ~MaxOffset, DL, MVT::i32); MachineSDNode *MovHighBits = CurDAG->getMachineNode( diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp index c85d7124f62bb..9d44d4c5424a3 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -6465,7 +6465,7 @@ AMDGPUInstructionSelector::selectMUBUFScratchOffen(MachineOperand &Root) const { // TODO: Should this be inside the render function? The iterator seems to // move. - const uint32_t MaxOffset = SIInstrInfo::getMaxMUBUFImmOffset(*Subtarget); + const int64_t MaxOffset = SIInstrInfo::getMaxMUBUFImmOffset(*Subtarget); BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::V_MOV_B32_e32), HighBits) .addImm(Offset & ~MaxOffset); diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp index c57ef9392a4ca..b8f2b50b8acad 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -4942,7 +4942,7 @@ bool AMDGPULegalizerInfo::loadInputValue( AMDGPUFunctionArgInfo::PreloadedValue ArgType) const { const SIMachineFunctionInfo *MFI = B.getMF().getInfo(); const ArgDescriptor *Arg = nullptr; - const TargetRegisterClass *ArgRC; + const TargetRegisterClass *ArgRC = nullptr; LLT ArgTy; CallingConv::ID CC = B.getMF().getFunction().getCallingConv(); diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp index 7c0a3fb466b14..cddfbdd7818db 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp @@ -2017,7 +2017,7 @@ bool AMDGPULibCalls::evaluateCall(CallInst *aCI, const FuncInfo &FInfo) { } } - Constant *nval0, *nval1; + Constant *nval0 = nullptr, *nval1 = nullptr; if (FuncVecSize == 1) { nval0 = ConstantFP::get(aCI->getType(), Val0[0]); if (hasTwoResults) diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp index 54fc33a4a47cd..3510e2b1bc2b5 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp @@ -471,8 +471,8 @@ bool AMDGPULowerVGPREncoding::updateSetregModeImm(MachineInstr &MI, MachineOperand *ImmOp = TII->getNamedOperand(MI, AMDGPU::OpName::imm); int64_t OldImm = ImmOp->getImm(); // Note that Offset is ignored for mode bits here. - int64_t NewImm = - (OldImm & ~AMDGPU::Hwreg::VGPR_MSB_MASK) | (SetregMode << VGPRMSBShift); + int64_t NewImm = (OldImm & ~int64_t(AMDGPU::Hwreg::VGPR_MSB_MASK)) | + (SetregMode << VGPRMSBShift); ImmOp->setImm(NewImm); return NewImm != OldImm; } diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp index c0802de2763dc..7db637eaa0745 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp @@ -44,7 +44,8 @@ #include "AMDGPU.h" #include "Utils/AMDGPUBaseInfo.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/MemorySSA.h" +#include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/IR/AttributeMask.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" @@ -81,7 +82,9 @@ namespace { class AMDGPURewriteOutArguments : public FunctionPass { private: const DataLayout *DL = nullptr; - MemoryDependenceResults *MDA = nullptr; + MemorySSA *MSSA = nullptr; + MemorySSAUpdater *MSSAU = nullptr; + AAResults *AA = nullptr; Type *getStoredType(Value &Arg) const; Type *getOutArgumentType(Argument &Arg) const; @@ -92,7 +95,8 @@ class AMDGPURewriteOutArguments : public FunctionPass { AMDGPURewriteOutArguments() : FunctionPass(ID) {} void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); + AU.addRequired(); FunctionPass::getAnalysisUsage(AU); } @@ -104,7 +108,7 @@ class AMDGPURewriteOutArguments : public FunctionPass { INITIALIZE_PASS_BEGIN(AMDGPURewriteOutArguments, DEBUG_TYPE, "AMDGPU Rewrite Out Arguments", false, false) -INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass) +INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) INITIALIZE_PASS_END(AMDGPURewriteOutArguments, DEBUG_TYPE, "AMDGPU Rewrite Out Arguments", false, false) @@ -170,6 +174,49 @@ bool AMDGPURewriteOutArguments::doInitialization(Module &M) { return false; } +static StoreInst *findStoreForOutArgument(BasicBlock *BB, Argument *OutArg, + MemorySSA &MSSA, + BatchAAResults &BAA) { + MemoryLocation ArgLoc = MemoryLocation::getBeforeOrAfter(OutArg); + const auto *Accesses = MSSA.getBlockAccesses(BB); + if (!Accesses) + return nullptr; + + for (const MemoryAccess &Access : reverse(*Accesses)) { + const auto *UseOrDef = dyn_cast(&Access); + if (!UseOrDef) + continue; + + Instruction *I = UseOrDef->getMemoryInst(); + + // Return the must-alias store to the out argument. + if (auto *Store = dyn_cast(I)) + if (Store->getPointerOperand() == OutArg) + return Store; + + if (auto *FI = dyn_cast(I)) + if (FI->getOrdering() == AtomicOrdering::Release) + continue; + + if (auto *LI = dyn_cast(I)) { + if (LI->isAtomic()) { + // May-alias reads with monotonic ordering are ignored. + if (isStrongerThan(LI->getOrdering(), AtomicOrdering::Monotonic)) + return nullptr; + continue; + } + } + + // Any other memory access that writes the location prevents the + // rewrite. + // FIXME: should handle aliasing reads too. + if (isModSet(BAA.getModRefInfo(I, ArgLoc))) + return nullptr; + } + + return nullptr; +} + bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { if (skipFunction(F)) return false; @@ -179,8 +226,6 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { AMDGPU::isEntryFunctionCC(F.getCallingConv())) return false; - MDA = &getAnalysis().getMemDep(); - unsigned ReturnNumRegs = 0; // Maps an out-argument number to its field index in the return struct. // Fields are in processing order, which the retry loop below can reorder @@ -222,6 +267,13 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { if (Returns.empty()) return false; + AA = &getAnalysis().getAAResults(); + MSSA = &getAnalysis().getMSSA(); + + BatchAAResults BatchAA(*AA); + MemorySSAUpdater MSSAUpdater(MSSA); + MSSAU = &MSSAUpdater; + bool Changing; do { @@ -254,17 +306,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { for (ReturnInst *RI : Returns) { BasicBlock *BB = RI->getParent(); - MemDepResult Q = MDA->getPointerDependencyFrom( - MemoryLocation::getBeforeOrAfter(OutArg), true, BB->end(), BB, RI); - StoreInst *SI = nullptr; - if (Q.isDef()) - SI = dyn_cast(Q.getInst()); - - // MDA stops at the first may-aliasing store, which need not be to this - // argument; only fold a store whose pointer is exactly OutArg. - if (SI && SI->getPointerOperand() != OutArg) - SI = nullptr; - + StoreInst *SI = findStoreForOutArgument(BB, OutArg, *MSSA, BatchAA); if (SI) { LLVM_DEBUG(dbgs() << "Found out argument store: " << *SI << '\n'); ReplaceableStores.emplace_back(RI, SI); @@ -291,6 +333,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { } ValVec.emplace_back(OutArg, ReplVal); + MSSAU->removeMemoryAccess(Store.second); Store.second->eraseFromParent(); } diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 9c0a5f2ec2773..6747f60cb9c9d 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -8296,7 +8296,7 @@ bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr, unsigned &UsedOprMask) { } } - unsigned CntValMask = PrevOprMask ^ UsedOprMask; + int64_t CntValMask = PrevOprMask ^ UsedOprMask; DepCtr = (DepCtr & ~CntValMask) | CntVal; return true; } diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index bd087fae75403..9cf33b4ccbb87 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -1023,7 +1023,8 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM, setOperationAction(ISD::MUL, MVT::i1, Promote); if (Subtarget->hasBF16ConversionInsts()) { - setOperationAction(ISD::FP_ROUND, {MVT::bf16, MVT::v2bf16}, Custom); + setOperationAction({ISD::FP_ROUND, ISD::STRICT_FP_ROUND}, + {MVT::bf16, MVT::v2bf16}, Custom); setOperationAction(ISD::BUILD_VECTOR, MVT::v2bf16, Legal); } @@ -2682,7 +2683,7 @@ SDValue SITargetLowering::getPreloadedValue( SelectionDAG &DAG, const SIMachineFunctionInfo &MFI, EVT VT, AMDGPUFunctionArgInfo::PreloadedValue PVID) const { const ArgDescriptor *Reg = nullptr; - const TargetRegisterClass *RC; + const TargetRegisterClass *RC = nullptr; LLT Ty; CallingConv::ID CC = DAG.getMachineFunction().getFunction().getCallingConv(); @@ -6014,7 +6015,8 @@ static MachineBasicBlock *lowerWaveReduce(MachineInstr &MI, MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); Register Op1L_Op0H_Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); - Register CarryReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); + Register CarryReg = + MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass); Register AddReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); Register NegatedValLo = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); @@ -6041,9 +6043,23 @@ static MachineBasicBlock *lowerWaveReduce(MachineInstr &MI, BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), DestSub0) .addReg(Op1L) .addReg(LowOpcode); - BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_HI_U32), CarryReg) - .addReg(Op1L) - .addReg(LowOpcode); + if (ST.hasScalarMulHiInsts()) { + BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_HI_U32), CarryReg) + .addReg(Op1L) + .addReg(LowOpcode); + } else { + Register VCarryReg = + MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); + Register LowOpVGPR = + MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); + BuildMI(BB, MI, DL, TII->get(AMDGPU::COPY), LowOpVGPR) + .addReg(LowOpcode); + BuildMI(BB, MI, DL, TII->get(AMDGPU::V_MUL_HI_U32_e64), VCarryReg) + .addReg(Op1L) + .addReg(LowOpVGPR); + BuildMI(BB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), CarryReg) + .addReg(VCarryReg); + } BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), Op1H_Op0L_Reg) .addReg(Op1H) .addReg(LowOpcode); @@ -6364,10 +6380,23 @@ static MachineBasicBlock *lowerWaveReduce(MachineInstr &MI, ActiveBits.addReg(NewActiveBitsReg).addMBB(ComputeLoop); // Creating branching - unsigned CMPOpc = IsWave32 ? AMDGPU::S_CMP_LG_U32 : AMDGPU::S_CMP_LG_U64; - BuildMI(*ComputeLoop, I, DL, TII->get(CMPOpc)) - .addReg(NewActiveBitsReg) - .addImm(0); + MachineInstrBuilder SetSCCInstr; + if (!ST.hasScalarCompareEq64()) { + // For targets <= gfx7, use an S_OR_B32/B64 instruction to set SCC. + Register LaneMaskReg = MRI.createVirtualRegister(WaveMaskRegClass); + unsigned CMPOpc = IsWave32 ? AMDGPU::S_OR_B32 : AMDGPU::S_OR_B64; + SetSCCInstr = + BuildMI(*ComputeLoop, I, DL, TII->get(CMPOpc), LaneMaskReg); + } else { + unsigned CMPOpc = + IsWave32 ? AMDGPU::S_CMP_LG_U32 : AMDGPU::S_CMP_LG_U64; + SetSCCInstr = BuildMI(*ComputeLoop, I, DL, TII->get(CMPOpc)); + } + SetSCCInstr.addReg(NewActiveBitsReg); + if (ST.hasScalarCompareEq64()) + SetSCCInstr.addImm(0); + else + SetSCCInstr.addReg(NewActiveBitsReg); BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::S_CBRANCH_SCC1)) .addMBB(ComputeLoop); @@ -8235,6 +8264,30 @@ void SITargetLowering::ReplaceNodeResults(SDNode *N, case ISD::INTRINSIC_WO_CHAIN: { unsigned IID = N->getConstantOperandVal(0); switch (IID) { + case Intrinsic::amdgcn_wave_reduce_min: + case Intrinsic::amdgcn_wave_reduce_umin: + case Intrinsic::amdgcn_wave_reduce_max: + case Intrinsic::amdgcn_wave_reduce_umax: + case Intrinsic::amdgcn_wave_reduce_add: + case Intrinsic::amdgcn_wave_reduce_sub: + case Intrinsic::amdgcn_wave_reduce_and: + case Intrinsic::amdgcn_wave_reduce_or: + case Intrinsic::amdgcn_wave_reduce_xor: { + EVT VT = N->getValueType(0); + if (isTypeLegal(VT)) + return; + SDLoc SL(N); + bool NeedsSignExt = IID == Intrinsic::amdgcn_wave_reduce_min || + IID == Intrinsic::amdgcn_wave_reduce_max || + IID == Intrinsic::amdgcn_wave_reduce_add || + IID == Intrinsic::amdgcn_wave_reduce_sub; + unsigned ExtOpc = NeedsSignExt ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; + SDValue ExtSrc = DAG.getNode(ExtOpc, SL, MVT::i32, N->getOperand(1)); + SDValue Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32, + N->getOperand(0), ExtSrc, N->getOperand(2)); + Results.push_back(DAG.getNode(ISD::TRUNCATE, SL, VT, Result)); + return; + } case Intrinsic::amdgcn_make_buffer_rsrc: Results.push_back(lowerPointerAsRsrcIntrin(N, DAG)); return; @@ -8644,7 +8697,8 @@ SDValue SITargetLowering::splitFP_ROUNDVectorOp(SDValue Op, } SDValue SITargetLowering::lowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const { - SDValue Src = Op.getOperand(0); + bool IsStrict = Op->isStrictFPOpcode(); + SDValue Src = Op.getOperand(IsStrict ? 1 : 0); EVT SrcVT = Src.getValueType(); EVT DstVT = Op.getValueType(); @@ -8687,6 +8741,11 @@ SDValue SITargetLowering::lowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const { // hardware f32 -> bf16 instruction. EVT F32VT = SrcVT.changeElementType(*DAG.getContext(), MVT::f32); SDValue Rod = expandRoundInexactToOdd(F32VT, Src, DL, DAG); + if (IsStrict) { + return DAG.getNode( + ISD::STRICT_FP_ROUND, DL, {DstVT, MVT::Other}, + {Op.getOperand(0), Rod, DAG.getTargetConstant(0, DL, MVT::i32)}); + } return DAG.getNode(ISD::FP_ROUND, DL, DstVT, Rod, DAG.getTargetConstant(0, DL, MVT::i32)); } diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp index e945db946c158..81b7bf7f769ad 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -4303,7 +4303,7 @@ SIInstrInfo::convertToThreeAddressImpl(MachineInstr &MI, // If we have an SGPR input, we will violate the constant bus restriction. (ST.getConstantBusLimit(Opc) > 1 || !Src0->isReg() || !RI.isSGPRReg(MBB.getParent()->getRegInfo(), Src0->getReg()))) { - MachineInstr *DefMI; + MachineInstr *DefMI = nullptr; int64_t Imm; if (!Src0Literal && getFoldableImm(Src2, Imm, &DefMI)) { @@ -10289,7 +10289,7 @@ bool SIInstrInfo::isBufferSMRD(const MachineInstr &MI) const { // offsets within the given alignment can be added to the resulting ImmOffset. bool SIInstrInfo::splitMUBUFOffset(uint32_t Imm, uint32_t &SOffset, uint32_t &ImmOffset, Align Alignment) const { - const uint32_t MaxOffset = SIInstrInfo::getMaxMUBUFImmOffset(ST); + const uint64_t MaxOffset = SIInstrInfo::getMaxMUBUFImmOffset(ST); const uint32_t MaxImm = alignDown(MaxOffset, Alignment.value()); uint32_t Overflow = 0; diff --git a/llvm/lib/Target/AMDGPU/VOP3Instructions.td b/llvm/lib/Target/AMDGPU/VOP3Instructions.td index f2a2f2b3a2499..ebbe89981e4ef 100644 --- a/llvm/lib/Target/AMDGPU/VOP3Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP3Instructions.td @@ -1794,7 +1794,7 @@ class VOP3_CVT_SR_FP16_TiedInput_Profile : VOP3_CVT_SCALE_F1632_FP // FIXME: GlobalISel cannot distinguish f16 and bf16 and may start using bf16 patterns // instead of less complex f16. Disable GlobalISel for these for now. -def bf16_fpround : PatFrag <(ops node:$src0), (fpround $src0), [{ return true; }]> { +def bf16_fpround : PatFrag <(ops node:$src0), (any_fpround $src0), [{ return true; }]> { let GISelPredicateCode = [{return false;}]; } diff --git a/llvm/lib/Target/BPF/BPFMIPeephole.cpp b/llvm/lib/Target/BPF/BPFMIPeephole.cpp index c6fa0bf6d23bc..2adf4ea6fdfe7 100644 --- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp +++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp @@ -155,7 +155,11 @@ bool BPFMIPeephole::isInsnFrom32Def(MachineInstr *DefInsn) bool BPFMIPeephole::isMovFrom32Def(MachineInstr *MovMI) { - MachineInstr *DefInsn = MRI->getVRegDef(MovMI->getOperand(1).getReg()); + const MachineOperand &Src = MovMI->getOperand(1); + if (Src.getSubReg()) + return false; + + MachineInstr *DefInsn = MRI->getVRegDef(Src.getReg()); LLVM_DEBUG(dbgs() << " Def of Mov Src:"); LLVM_DEBUG(DefInsn->dump()); diff --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp index fca33480265ad..b36c0b4e2faaf 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp @@ -1077,7 +1077,13 @@ HexagonTargetLowering::buildHvxVectorReg(ArrayRef Values, SDValue HalfV = getZero(dl, VecTy, DAG); if (VecHist[n] > 1) { - SDValue SplatV = DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Words[n]); + // Always splat at word (i32) granularity so that the SPLAT_VECTOR node + // is selected as PS_vsplatrw (word broadcast) rather than PS_vsplatrb + // (byte broadcast of the low byte only), which would corrupt multi-byte + // element types. + MVT WordVecTy = MVT::getVectorVT(MVT::i32, HwLen / 4); + SDValue WordSplat = DAG.getNode(ISD::SPLAT_VECTOR, dl, WordVecTy, Words[n]); + SDValue SplatV = DAG.getBitcast(VecTy, WordSplat); HalfV = DAG.getNode(HexagonISD::VALIGN, dl, VecTy, {HalfV, SplatV, DAG.getConstant(HwLen/2, dl, MVT::i32)}); } diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 5672ec9f9a4de..bbd1738cd5117 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -1433,6 +1433,27 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, emitSiFiveCLICStackSwap(MF, MBB, MBBI, DL); } +static MCRegister getPhysicalGPR(const TargetRegisterInfo &TRI, + MCRegister Reg) { + if (RISCV::GPRRegClass.contains(Reg)) + return Reg; + + std::array RegisterClasses = { + &RISCV::GPRF16RegClass, &RISCV::GPRF32RegClass}; + std::array SubIdx = {RISCV::sub_16, RISCV::sub_32}; + + for (auto [RegClass, SubReg] : zip(RegisterClasses, SubIdx)) { + if (RegClass->contains(Reg)) { + if (MCRegister Super = + TRI.getMatchingSuperReg(Reg, SubReg, &RISCV::GPRRegClass)) + return Super; + } + } + + llvm::reportFatalInternalError( + "getPhysicalGPR called with unsupported register"); +} + static MCRegister getLargestFPRegisterOrZero(const RISCVSubtarget &STI, const TargetRegisterInfo &TRI, MCRegister Reg) { @@ -1481,7 +1502,12 @@ void RISCVFrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero, for (MCRegister Reg : RegsToZero.set_bits()) { if (TRI.isGeneralPurposeRegister(MF, Reg)) { - FinalRegsToZero.set(Reg.id()); + FinalRegsToZero.set(getPhysicalGPR(TRI, Reg).id()); + } else if (RISCV::GPRPairRegClass.contains(Reg)) { + FinalRegsToZero.set( + getPhysicalGPR(TRI, TRI.getSubReg(Reg, RISCV::sub_gpr_even)).id()); + FinalRegsToZero.set( + getPhysicalGPR(TRI, TRI.getSubReg(Reg, RISCV::sub_gpr_odd)).id()); } else if (TRI.isFPRegister(Reg)) { if (MCRegister MaybeReg = getLargestFPRegisterOrZero(STI, TRI, Reg)) FinalRegsToZero.set(MaybeReg.id()); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index c0b69d50f8fef..fda994a04b00f 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -6314,6 +6314,34 @@ static SDValue tryWidenMaskForShuffle(SDValue Op, SelectionDAG &DAG) { return DAG.getBitcast(VT, DAG.getVectorShuffle(NewVT, DL, V0, V1, NewMask)); } +// Match an interleave shuffle that forms a P-extension packed zip: +// -> zip*p/wzip*p +static SDValue lowerVECTOR_SHUFFLEAsPZip(ShuffleVectorSDNode *SVN, + SelectionDAG &DAG) { + SDValue V1 = SVN->getOperand(0); + SDValue V2 = SVN->getOperand(1); + SDLoc DL(SVN); + MVT VT = SVN->getSimpleValueType(0); + unsigned NumElts = VT.getVectorNumElements(); + ArrayRef Mask = SVN->getMask(); + + if (VT != MVT::v8i8 && VT != MVT::v4i16) + return SDValue(); + + SmallVector StartIndexes; + if (!V2.isUndef() && + ShuffleVectorInst::isInterleaveMask(Mask, 2, NumElts * 2, StartIndexes)) { + unsigned EvenSrc = StartIndexes[0]; + unsigned OddSrc = StartIndexes[1]; + if (EvenSrc == 0 && OddSrc == NumElts) + return DAG.getNode(RISCVISD::PZIP, DL, VT, V1, V2); + if (EvenSrc == NumElts && OddSrc == 0) + return DAG.getNode(RISCVISD::PZIP, DL, VT, V2, V1); + } + + return SDValue(); +} + SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const { SDValue V1 = Op.getOperand(0); @@ -6348,6 +6376,9 @@ SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, DAG.getConstant(VT.getSizeInBits() / 2, DL, MVT::i64)); return DAG.getBitcast(VT, Srl); } + + if (SDValue V = lowerVECTOR_SHUFFLEAsPZip(SVN, DAG)) + return V; return SDValue(); } @@ -13213,27 +13244,14 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, if (VecVT.getVectorElementType() == MVT::i1) return widenVectorOpsToi8(Op, DL, DAG); - // Convert to scalable vectors first. - if (VecVT.isFixedLengthVector()) { - MVT ContainerVT = getContainerForFixedLengthVector(VecVT); - SmallVector Ops(Factor); - for (unsigned i = 0U; i < Factor; ++i) - Ops[i] = convertToScalableVector(ContainerVT, Op.getOperand(i), DAG, - Subtarget); - - SmallVector VTs(Factor, ContainerVT); - SDValue NewDeinterleave = - DAG.getNode(ISD::VECTOR_DEINTERLEAVE, DL, VTs, Ops); + bool IsFixedVector = VecVT.isFixedLengthVector(); - SmallVector Res(Factor); - for (unsigned i = 0U; i < Factor; ++i) - Res[i] = convertFromScalableVector(VecVT, NewDeinterleave.getValue(i), - DAG, Subtarget); - return DAG.getMergeValues(Res, DL); - } + MVT ContainerVecVT = VecVT; + if (IsFixedVector) + ContainerVecVT = getContainerForFixedLengthVector(VecVT); // If concatenating would exceed LMUL=8, we need to split. - if ((VecVT.getSizeInBits().getKnownMinValue() * Factor) > + if ((ContainerVecVT.getSizeInBits().getKnownMinValue() * Factor) > (8 * RISCV::RVVBitsPerBlock)) { SmallVector Ops(Factor * 2); for (unsigned i = 0; i != Factor; ++i) { @@ -13257,7 +13275,7 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, return DAG.getMergeValues(Res, DL); } - if (Subtarget.hasStdExtZvzip() && Factor == 2) { + if (Subtarget.hasStdExtZvzip() && Factor == 2 && !IsFixedVector) { MVT VT = Op->getSimpleValueType(0); MVT NewVT = VT.getDoubleNumVectorElementsVT(); if (isTypeLegal(NewVT) && isLegalVTForZvzipOperand(VT, Subtarget)) { @@ -13283,7 +13301,7 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, Ops.append(PowerOf2Ceil(Factor) - Factor, DAG.getUNDEF(VecVT)); SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT, Ops); - if (Factor == 2) { + if (Factor == 2 && !IsFixedVector) { // We can deinterleave through vnsrl.wi if the element type is smaller than // ELEN if (VecVT.getScalarSizeInBits() < Subtarget.getELen()) { @@ -13322,27 +13340,63 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, } // Store with unit-stride store and load it back with segmented load. + SDValue Mask, VL; MVT XLenVT = Subtarget.getXLenVT(); - auto [Mask, VL] = getDefaultScalableVLOps(VecVT, DL, DAG, Subtarget); - SDValue Passthru = DAG.getUNDEF(ConcatVT); - - // Allocate a stack slot. - Align Alignment = DAG.getReducedAlign(VecVT, /*UseABI=*/false); - SDValue StackPtr = - DAG.CreateStackTemporary(ConcatVT.getStoreSize(), Alignment); auto &MF = DAG.getMachineFunction(); - auto FrameIndex = cast(StackPtr.getNode())->getIndex(); - auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex); + SDValue Chain = DAG.getEntryNode(); + Align Alignment = DAG.getReducedAlign(VecVT, /*UseABI=*/false); + SDValue StackPtr; + MachinePointerInfo PtrInfo; + if (IsFixedVector) { + // Calculating the stack size. + ElementCount ActualConcatEC = + VecVT.getVectorElementCount().multiplyCoefficientBy(Factor); + EVT ConcatEVT = EVT::getVectorVT( + *DAG.getContext(), VecVT.getVectorElementType(), ActualConcatEC); + StackPtr = DAG.CreateStackTemporary(ConcatEVT.getStoreSize(), Alignment); + auto FrameIndex = cast(StackPtr.getNode())->getIndex(); + PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex); + + // If this is a fixed vector, instead of using the concat vector, we simply + // store each fixed vector operand directly onto the stack, individually. + // The reason being that if the fixed vector is (much) smaller than the + // container vector, we will be wasting space on stack. + TypeSize VecSize = VecVT.getStoreSize(); + SDValue BasePtr = StackPtr; + MachinePointerInfo PI = PtrInfo; + SmallVector Tokens(Factor); + for (auto [Idx, FieldOp] : enumerate(Op->op_values())) { + if (Idx) { + // Advance the pointer. + BasePtr = DAG.getObjectPtrOffset(DL, BasePtr, VecSize); + PI = PI.getWithOffset(VecSize); + } + Tokens[Idx] = DAG.getStore(Chain, DL, FieldOp, BasePtr, PI, Alignment); + } + Chain = DAG.getTokenFactor(DL, Tokens); - SDValue StoreOps[] = {DAG.getEntryNode(), - DAG.getTargetConstant(Intrinsic::riscv_vse, DL, XLenVT), - Concat, StackPtr, VL}; + // Calculating Mask and VL for later usages. + std::tie(Mask, VL) = + getDefaultVLOps(VecVT, ContainerVecVT, DL, DAG, Subtarget); + ConcatVT = getContainerForFixedLengthVector(ConcatVT); + } else { + std::tie(Mask, VL) = getDefaultScalableVLOps(VecVT, DL, DAG, Subtarget); + StackPtr = DAG.CreateStackTemporary(ConcatVT.getStoreSize(), Alignment); + auto FrameIndex = cast(StackPtr.getNode())->getIndex(); + PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex); + + SDValue StoreOps[] = { + Chain, DAG.getTargetConstant(Intrinsic::riscv_vse, DL, XLenVT), Concat, + StackPtr, VL}; - SDValue Chain = DAG.getMemIntrinsicNode( - ISD::INTRINSIC_VOID, DL, DAG.getVTList(MVT::Other), StoreOps, - ConcatVT.getVectorElementType(), PtrInfo, Alignment, - MachineMemOperand::MOStore, LocationSize::beforeOrAfterPointer()); + Chain = DAG.getMemIntrinsicNode( + ISD::INTRINSIC_VOID, DL, DAG.getVTList(MVT::Other), StoreOps, + ConcatVT.getVectorElementType(), PtrInfo, Alignment, + MachineMemOperand::MOStore, LocationSize::beforeOrAfterPointer()); + } + // Load it back with segmented load. + SDValue Passthru = DAG.getUNDEF(ConcatVT); static const Intrinsic::ID VlsegIntrinsicsIds[] = { Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask, Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask, @@ -13360,8 +13414,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC, DL, XLenVT), DAG.getTargetConstant(Log2_64(VecVT.getScalarSizeInBits()), DL, XLenVT)}; - unsigned Sz = - Factor * VecVT.getVectorMinNumElements() * VecVT.getScalarSizeInBits(); + unsigned Sz = Factor * ContainerVecVT.getVectorMinNumElements() * + ContainerVecVT.getScalarSizeInBits(); EVT VecTupTy = MVT::getRISCVVectorTupleVT(Sz, Factor); SDValue Load = DAG.getMemIntrinsicNode( @@ -13371,9 +13425,14 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, SmallVector Res(Factor); - for (unsigned i = 0U; i < Factor; ++i) - Res[i] = DAG.getNode(RISCVISD::TUPLE_EXTRACT, DL, VecVT, Load, - DAG.getTargetConstant(i, DL, MVT::i32)); + for (unsigned i = 0U; i < Factor; ++i) { + SDValue FieldRes = + DAG.getNode(RISCVISD::TUPLE_EXTRACT, DL, ContainerVecVT, Load, + DAG.getTargetConstant(i, DL, MVT::i32)); + if (IsFixedVector) + FieldRes = convertFromScalableVector(VecVT, FieldRes, DAG, Subtarget); + Res[i] = FieldRes; + } return DAG.getMergeValues(Res, DL); } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 1f547fe3ff2a2..7fa7c96ca99ca 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -1908,6 +1908,12 @@ def SDT_RISCVPackedUnary : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>; def riscv_psabs : RVSDNode<"PSABS", SDT_RISCVPackedUnary>; +// Interleave two packed vectors. +def SDT_RISCVPZip : SDTypeProfile<1, 2, [SDTCisVec<0>, + SDTCisSameAs<0, 1>, + SDTCisSameAs<0, 2>]>; +def riscv_pzip : RVSDNode<"PZIP", SDT_RISCVPZip>; + // Add one to the immediate. Used by RISCVISD::SATI. def IncImm : SDNodeXFormgetTargetConstant(N->getZExtValue() + 1, SDLoc(N), @@ -2264,6 +2270,16 @@ let append Predicates = [IsRV32] in { def : Pat<(v4i16 (zext (v4i8 GPR:$rs))), (WZIP8P GPR:$rs, (v4i8 X0))>; def : Pat<(v2i32 (zext (v2i16 GPR:$rs))), (WZIP16P GPR:$rs, (v2i16 X0))>; + // Packed zip. + def : Pat<(v8i8 (riscv_pzip (v8i8 GPRPair:$rs1), + (v8i8 GPRPair:$rs2))), + (WZIP8P (i32 (EXTRACT_SUBREG GPRPair:$rs1, sub_gpr_even)), + (i32 (EXTRACT_SUBREG GPRPair:$rs2, sub_gpr_even)))>; + def : Pat<(v4i16 (riscv_pzip (v4i16 GPRPair:$rs1), + (v4i16 GPRPair:$rs2))), + (WZIP16P (i32 (EXTRACT_SUBREG GPRPair:$rs1, sub_gpr_even)), + (i32 (EXTRACT_SUBREG GPRPair:$rs2, sub_gpr_even)))>; + // Sign-extend patterns using pwadd with zero def : Pat<(v4i16 (sext (v4i8 GPR:$rs))), (PWADD_B GPR:$rs, (v4i8 X0))>; def : Pat<(v2i32 (sext (v2i16 GPR:$rs))), (PWADD_H GPR:$rs, (v2i16 X0))>; @@ -2749,6 +2765,11 @@ let append Predicates = [IsRV64] in { def : Pat<(v4i16 (zext_invec (v8i8 GPR:$rs))), (ZIP8P GPR:$rs, (v8i8 X0))>; def : Pat<(v2i32 (zext_invec (v4i16 GPR:$rs))), (ZIP16P GPR:$rs, (v4i16 X0))>; + // Packed zip. + def : Pat<(v8i8 (riscv_pzip (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))), + (ZIP8P GPR:$rs1, GPR:$rs2)>; + def : Pat<(v4i16 (riscv_pzip (v4i16 GPR:$rs1), (v4i16 GPR:$rs2))), + (ZIP16P GPR:$rs1, GPR:$rs2)>; // Sign extend inreg patterns using psext. sext_invec is lowered to // zext_invec+sext_inreg. def : Pat<(v4i16 (sext_inreg GPR:$rs1, v4i8)), (PSEXT_H_B GPR:$rs1)>; diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td index a3f968b5ab76f..07f002fccfa66 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -570,6 +570,7 @@ def GPRF16C : RISCVRegisterClass<[f16], 16, (add (sequence "X%u_H", 10, 15), (sequence "X%u_H", 8, 9))> { let DecoderMethod = "DecodeSimpleRegisterClass"; } +def GPRF16X0 : RISCVRegisterClass<[f16], 16, (add X0_H)>; def GPRF16NoX0 : RISCVRegisterClass<[f16], 16, (sub GPRF16, X0_H)>; def GPRF32 : RISCVRegisterClass<[f32], 32, (add (sequence "X%u_W", 10, 17), @@ -584,6 +585,7 @@ def GPRF32C : RISCVRegisterClass<[f32], 32, (add (sequence "X%u_W", 10, 15), (sequence "X%u_W", 8, 9))> { let DecoderMethod = "DecodeSimpleRegisterClass"; } +def GPRF32X0 : RISCVRegisterClass<[f32], 32, (add X0_W)>; def GPRF32NoX0 : RISCVRegisterClass<[f32], 32, (sub GPRF32, X0_W)>; //===----------------------------------------------------------------------===// @@ -1024,6 +1026,6 @@ def MR0 : RISCVRegisterClass<[i8, v8i1], 8, (add M0)>; // Register categories. // -def GeneralPurposeRegisters : RegisterCategory<[GPR]>; +def GeneralPurposeRegisters : RegisterCategory<[GPR, GPRF16, GPRF32]>; -def FixedRegisters : RegisterCategory<[GPRX0]>; +def FixedRegisters : RegisterCategory<[GPRX0, GPRF16X0, GPRF32X0]>; diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index b39806b5848e1..6ddc4c789a079 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -562,8 +562,8 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { verify(*ST.getInstrInfo()); } -static bool legalizeExtractVectorElt(LegalizerHelper &Helper, MachineInstr &MI, - SPIRVGlobalRegistry *GR) { +static bool legalizeExtractVectorElt(LegalizerHelper &Helper, + MachineInstr &MI) { MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = MI.getOperand(1).getReg(); @@ -577,8 +577,7 @@ static bool legalizeExtractVectorElt(LegalizerHelper &Helper, MachineInstr &MI, return true; } -static bool legalizeInsertVectorElt(LegalizerHelper &Helper, MachineInstr &MI, - SPIRVGlobalRegistry *GR) { +static bool legalizeInsertVectorElt(LegalizerHelper &Helper, MachineInstr &MI) { MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = MI.getOperand(1).getReg(); @@ -726,9 +725,9 @@ bool SPIRVLegalizerInfo::legalizeCustom( case TargetOpcode::G_BITCAST: return legalizeBitcast(Helper, MI); case TargetOpcode::G_EXTRACT_VECTOR_ELT: - return legalizeExtractVectorElt(Helper, MI, GR); + return legalizeExtractVectorElt(Helper, MI); case TargetOpcode::G_INSERT_VECTOR_ELT: - return legalizeInsertVectorElt(Helper, MI, GR); + return legalizeInsertVectorElt(Helper, MI); case TargetOpcode::G_INTRINSIC: case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS: return legalizeIntrinsic(Helper, MI); diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index d499dc43dcab6..1d83ee40b9bc1 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -1835,8 +1835,10 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction( Insn.operands = x86OperandSets[Insn.spec->operands]; Insn.length = Insn.readerCursor - Insn.startLocation; Size = Insn.length; - if (Size > 15) + if (Size > 15) { LLVM_DEBUG(dbgs() << "Instruction exceeds 15-byte limit"); + return Fail; + } bool Ret = translateInstruction(Instr, Insn, this); if (!Ret) { diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 1496d3b4a8b22..a74800a1f7e86 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -108,10 +108,9 @@ def FeatureMMX : SubtargetFeature<"mmx","HasMMX", "true", def FeatureX86_64 : SubtargetFeature<"64bit", "HasX86_64", "true", "Support 64-bit instructions", [], InlineIgnore>; -// TODO: This should not be InlineIgnore, as it affects the atomics ABI. def FeatureCX16 : SubtargetFeature<"cx16", "HasCX16", "true", "64-bit with cmpxchg16b (this is true for most x86-64 chips, but not the first AMD chips)", - [FeatureCX8], InlineIgnore>; + [FeatureCX8]>; def FeatureSSE4A : SubtargetFeature<"sse4a", "HasSSE4A", "true", "Support SSE 4a instructions", [FeatureSSE3]>; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index cfbaca6059c42..46edb6c001955 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -645,6 +645,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::FROUNDEVEN, VT, Action); setOperationAction(ISD::FTRUNC, VT, Action); setOperationAction(ISD::FLDEXP, VT, Action); + setOperationAction(ISD::FFREXP, VT, Action); setOperationAction(ISD::FSINCOSPI, VT, Action); }; diff --git a/llvm/lib/TargetParser/PPCTargetParser.cpp b/llvm/lib/TargetParser/PPCTargetParser.cpp index 106d07107ac8c..76c2c13ac53a4 100644 --- a/llvm/lib/TargetParser/PPCTargetParser.cpp +++ b/llvm/lib/TargetParser/PPCTargetParser.cpp @@ -145,5 +145,12 @@ std::optional> getPPCDefaultTargetFeatures(const Triple &T, } return Features; } + +bool isValidFeatureName(StringRef Name) { + ArrayRef A = BasicPPCFeatureKV; + // Binary search the array + const BasicSubtargetFeatureKV *F = llvm::lower_bound(A, Name); + return F != A.end() && StringRef(F->Key) == Name; +} } // namespace PPC } // namespace llvm diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 0c4cc5451e736..9001507b7c70f 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -3870,6 +3870,7 @@ static bool runAttributorOnFunctions(InformationCache &InfoCache, SetVector &Functions, AnalysisGetter &AG, CallGraphUpdater &CGUpdater, + FunctionAnalysisManager &FAM, bool DeleteFns, bool IsModulePass) { if (Functions.empty()) return false; @@ -3886,6 +3887,11 @@ static bool runAttributorOnFunctions(InformationCache &InfoCache, AttributorConfig AC(CGUpdater); AC.IsModulePass = IsModulePass; AC.DeleteFns = DeleteFns; + auto OREGetter = [&FAM](Function *F) -> OptimizationRemarkEmitter & { + return FAM.getResult(*F); + }; + AC.OREGetter = OREGetter; + AC.PassName = DEBUG_TYPE; /// Tracking callback for specialization of indirect calls. DenseMap>> @@ -4099,7 +4105,7 @@ PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) { CallGraphUpdater CGUpdater; BumpPtrAllocator Allocator; InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr); - if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater, + if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater, FAM, /* DeleteFns */ true, /* IsModulePass */ true)) { // FIXME: Think about passes we will preserve and add them here. return PreservedAnalyses::none(); @@ -4127,7 +4133,7 @@ PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C, CGUpdater.initialize(CG, C, AM, UR); BumpPtrAllocator Allocator; InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions); - if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater, + if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater, FAM, /* DeleteFns */ false, /* IsModulePass */ false)) { // FIXME: Think about passes we will preserve and add them here. diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 4d59f7dd2c3ee..99d86781cc122 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SCCIterator.h" @@ -2947,6 +2948,25 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A) : AAUndefinedBehavior(IRP, A) {} + struct UBInfo { + enum Kind { + NullPtrAccess, + UndefPtrAccess, + UndefBranchCondition, + UndefReturnValue, + NullReturnViolatesNonNull, + UndefCallArgument, + NullArgViolatesNonNull, + }; + + Kind K; + std::optional ArgNo; + + UBInfo(Kind K) : K(K), ArgNo(std::nullopt) {} + + UBInfo(Kind K, std::optional ArgNo) : K(K), ArgNo(ArgNo) {} + }; + /// See AbstractAttribute::updateImpl(...). // through a pointer (i.e. also branches etc.) ChangeStatus updateImpl(Attributor &A) override { @@ -2973,7 +2993,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { // Either we stopped and the appropriate action was taken, // or we got back a simplified value to continue. std::optional SimplifiedPtrOp = - stopOnUndefOrAssumed(A, PtrOp, &I); + stopOnUndefOrAssumed(A, PtrOp, &I, UBInfo::UndefPtrAccess); if (!SimplifiedPtrOp || !*SimplifiedPtrOp) return true; const Value *PtrOpVal = *SimplifiedPtrOp; @@ -2996,7 +3016,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace())) AssumedNoUBInsts.insert(&I); else - KnownUBInsts.insert(&I); + KnownUBInsts.try_emplace(&I, UBInfo::NullPtrAccess); return true; }; @@ -3013,8 +3033,8 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { // Either we stopped and the appropriate action was taken, // or we got back a simplified value to continue. - std::optional SimplifiedCond = - stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst); + std::optional SimplifiedCond = stopOnUndefOrAssumed( + A, BrInst->getCondition(), BrInst, UBInfo::UndefBranchCondition); if (!SimplifiedCond || !*SimplifiedCond) return true; AssumedNoUBInsts.insert(&I); @@ -3066,7 +3086,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { if (SimplifiedVal && !*SimplifiedVal) return true; if (!SimplifiedVal || isa(**SimplifiedVal)) { - KnownUBInsts.insert(&I); + KnownUBInsts.try_emplace(&I, UBInfo(UBInfo::UndefCallArgument, idx)); continue; } if (!ArgVal->getType()->isPointerTy() || @@ -3076,7 +3096,8 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { AA::hasAssumedIRAttr( A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull); if (IsKnownNonNull) - KnownUBInsts.insert(&I); + KnownUBInsts.try_emplace(&I, + UBInfo(UBInfo::NullArgViolatesNonNull, idx)); } return true; }; @@ -3085,8 +3106,8 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { auto &RI = cast(I); // Either we stopped and the appropriate action was taken, // or we got back a simplified return value to continue. - std::optional SimplifiedRetValue = - stopOnUndefOrAssumed(A, RI.getReturnValue(), &I); + std::optional SimplifiedRetValue = stopOnUndefOrAssumed( + A, RI.getReturnValue(), &I, UBInfo::UndefReturnValue); if (!SimplifiedRetValue || !*SimplifiedRetValue) return true; @@ -3110,7 +3131,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE, IsKnownNonNull); if (IsKnownNonNull) - KnownUBInsts.insert(&I); + KnownUBInsts.try_emplace(&I, UBInfo::NullReturnViolatesNonNull); } return true; @@ -3174,11 +3195,55 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { return false; } + /// Emit an optimization remark explaining why \p I is known to cause UB, + /// per \p Info, right before it is replaced with 'unreachable'. + static void emitUBRemark(Attributor &A, Instruction *I, const UBInfo &Info) { + auto Remark = [&](OptimizationRemark OR) { + switch (Info.K) { + case UBInfo::NullPtrAccess: + case UBInfo::UndefPtrAccess: { + return OR << "Memory access through a pointer known to be " + << ore::NV("Pointer", + getPointerOperand(I, /*AllowVolatile*/ true)) + << " is undefined behavior; replacing with 'unreachable'."; + } + case UBInfo::UndefBranchCondition: + return OR << "Branch condition known to be " + << ore::NV("Condition", cast(I)->getCondition()) + << " is undefined behavior; replacing with 'unreachable'."; + case UBInfo::UndefReturnValue: + case UBInfo::NullReturnViolatesNonNull: + return OR << "Value returned known to be " + << ore::NV("ReturnValue", + cast(I)->getReturnValue()) + << " is undefined behavior; replacing with 'unreachable'."; + case UBInfo::UndefCallArgument: + case UBInfo::NullArgViolatesNonNull: { + bool IsUndef = Info.K == UBInfo::UndefCallArgument; + CallBase &CB = *cast(I); + OR << "Argument " << ore::NV("ArgNo", *Info.ArgNo) + << " passed to parameter of "; + if (auto *Callee = dyn_cast_if_present(CB.getCalledOperand())) + OR << ore::NV("Callee", Callee); + else + OR << "the callee"; + return OR << " known to be " + << ore::NV("Argument", IsUndef ? "undef" : "null") + << " is undefined behavior; replacing with 'unreachable'."; + } + } + llvm_unreachable("Unknown UBInfo::Kind"); + }; + A.emitRemark(I, "UndefinedBehavior", Remark); + } + ChangeStatus manifest(Attributor &A) override { if (KnownUBInsts.empty()) return ChangeStatus::UNCHANGED; - for (Instruction *I : KnownUBInsts) + for (const auto &[I, Info] : KnownUBInsts) { + emitUBRemark(A, I, Info); A.changeToUnreachableAfterManifest(I); + } return ChangeStatus::CHANGED; } @@ -3211,8 +3276,9 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { /// Note however that instructions in this set may cause UB. protected: - /// A set of all live instructions _known_ to cause UB. - SmallPtrSet KnownUBInsts; + /// A map from all live instructions _known_ to cause UB to the reason why, + /// used to build actionable optimization remarks in manifest(). + MapVector KnownUBInsts; private: /// A set of all the (live) instructions that are assumed to _not_ cause UB. @@ -3221,14 +3287,14 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { // Should be called on updates in which if we're processing an instruction // \p I that depends on a value \p V, one of the following has to happen: // - If the value is assumed, then stop. - // - If the value is known but undef, then consider it UB. + // - If the value is known but undef, then consider it UB for \p K. // - Otherwise, do specific processing with the simplified value. // We return std::nullopt in the first 2 cases to signify that an appropriate // action was taken and the caller should stop. // Otherwise, we return the simplified value that the caller should // use for specific processing. std::optional stopOnUndefOrAssumed(Attributor &A, Value *V, - Instruction *I) { + Instruction *I, UBInfo::Kind K) { bool UsedAssumedInformation = false; std::optional SimplifiedV = A.getAssumedSimplified(IRPosition::value(*V), *this, @@ -3238,7 +3304,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { if (!SimplifiedV) { // If it is known (which we tested above) but it doesn't have a value, // then we can assume `undef` and hence the instruction is UB. - KnownUBInsts.insert(I); + KnownUBInsts.try_emplace(I, K); return std::nullopt; } if (!*SimplifiedV) @@ -3246,7 +3312,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { V = *SimplifiedV; } if (isa(V)) { - KnownUBInsts.insert(I); + KnownUBInsts.try_emplace(I, K); return std::nullopt; } return V; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index f630d1efbd7e7..f30a7b5e891ab 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -3416,9 +3416,7 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { // If our destination is not a vector, then make this a straight // scalar-scalar cast. if (!DestTy->isVectorTy()) { - Value *Elem = - Builder.CreateExtractElement(Src, - Constant::getNullValue(Type::getInt32Ty(CI.getContext()))); + Value *Elem = Builder.CreateExtractElement(Src, uint64_t{0}); return CastInst::Create(Instruction::BitCast, Elem, DestTy); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index e6deb548819e8..42c2983034e22 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3569,10 +3569,9 @@ Instruction *InstCombinerImpl::foldICmpBitCast(ICmpInst &Cmp) { // Fold the icmp based on the value of C // If C is M copies of an iK sized bit pattern, // then: - // => %E = extractelement %vec, i32 Elem + // => %E = extractelement %vec, i64 Elem // icmp iK %SplatVal, - Value *Elem = Builder.getInt32(Mask[0]); - Value *Extract = Builder.CreateExtractElement(Vec, Elem); + Value *Extract = Builder.CreateExtractElement(Vec, Mask[0]); Value *NewC = ConstantInt::get(EltTy, C->trunc(EltTy->getBitWidth())); return new ICmpInst(Pred, Extract, NewC); } diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index a5105b84c3117..830b220c21d54 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -203,33 +203,59 @@ void ReassociatePass::BuildRankMap(Function &F, } unsigned ReassociatePass::getRank(Value *V) { - Instruction *I = dyn_cast(V); - if (!I) { - if (isa(V)) return ValueRankMap[V]; // Function argument. - return 0; // Otherwise it's a global or constant, rank 0. - } - - if (unsigned Rank = ValueRankMap[I]) - return Rank; // Rank already known? - - // If this is an expression, return the 1+MAX(rank(LHS), rank(RHS)) so that - // we can reassociate expressions for code motion! Since we do not recurse - // for PHI nodes, we cannot have infinite recursion here, because there - // cannot be loops in the value graph that do not go through PHI nodes. - unsigned Rank = 0, MaxRank = RankMap[I->getParent()]; - for (unsigned i = 0, e = I->getNumOperands(); i != e && Rank != MaxRank; ++i) - Rank = std::max(Rank, getRank(I->getOperand(i))); + // Return 1+MAX(rank(LHS), rank(RHS)) for expressions so we can reassociate + // expressions for code motion. Use an explicit worklist rather than native + // recursion so long acyclic use-def chains do not overflow the stack. + struct RankWorkItem { + Value *V; + unsigned OpNo; + unsigned Rank; + }; - // If this is a 'not' or 'neg' instruction, do not count it for rank. This - // assures us that X and ~X will have the same rank. - if (!match(I, m_Not(m_Value())) && !match(I, m_Neg(m_Value())) && - !match(I, m_FNeg(m_Value()))) - ++Rank; + // Each item is one suspended recursive getRank() call. + // Completed ranks are folded back into the parent. + SmallVector Worklist; + Worklist.push_back(RankWorkItem{V, 0, 0}); + + while (true) { + RankWorkItem &Item = Worklist.back(); + Instruction *I = dyn_cast(Item.V); + unsigned Rank = 0; + if (!I) { + // Function argument, global or constant + Rank = isa(Item.V) ? ValueRankMap[Item.V] : 0; + } else if (ValueRankMap[I]) { + // Instruction that is not movable. + Rank = ValueRankMap[I]; + } else if (Item.OpNo == I->getNumOperands() || + Item.Rank == RankMap[I->getParent()]) { + // All operands were visited or the max block rank was reached. + Rank = Item.Rank; + // If this is a 'not' or 'neg' instruction, do not count it for rank. + // This assures us that X and ~X will have the same rank. + if (!match(I, m_Not(m_Value())) && !match(I, m_Neg(m_Value())) && + !match(I, m_FNeg(m_Value()))) + ++Rank; + + LLVM_DEBUG(dbgs() << "Calculated Rank[" << I->getName() << "] = " << Rank + << "\n"); + + ValueRankMap[I] = Rank; + } else { + Worklist.push_back(RankWorkItem{I->getOperand(Item.OpNo), 0, 0}); + continue; + } - LLVM_DEBUG(dbgs() << "Calculated Rank[" << V->getName() << "] = " << Rank - << "\n"); + // Once the current use-def node has a known rank, carry that rank back to + // the parent expression and advance past the operand that led here. + Worklist.pop_back(); + if (Worklist.empty()) + return Rank; - return ValueRankMap[I] = Rank; + RankWorkItem &Parent = Worklist.back(); + Parent.Rank = std::max(Parent.Rank, Rank); + ++Parent.OpNo; + } } // Canonicalize constants to RHS. Otherwise, sort the operands by rank. diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h index c5524d01fa76e..cd02ced2942d1 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h @@ -406,7 +406,7 @@ class VPBuilder { /// induction with \p Start and \p Step values, using \p Start + \p Current * /// \p Step. VPDerivedIVRecipe *createDerivedIV(InductionDescriptor::InductionKind Kind, - FPMathOperator *FPBinOp, VPIRValue *Start, + FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step) { return tryInsertInstruction( new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step)); @@ -527,8 +527,7 @@ class VPBuilder { /// with element type \p SourceElementTy. VPSingleDefRecipe *createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, - bool Reverse, bool FoldTail, - DebugLoc DL); + bool Reverse, DebugLoc DL); VPWidenMemIntrinsicRecipe *createWidenMemIntrinsic( Intrinsic::ID VectorIntrinsicID, ArrayRef CallArguments, @@ -970,6 +969,10 @@ class LoopVectorizationPlanner { /// loop. Asserts that the VPlan decision matches the legacy cost model. bool requiresScalarEpilogue(VPlan &Plan, ElementCount VF) const; + /// Returns true if \p Plan folds the tail by masking. Asserts that the + /// VPlan-based decision matches the legacy cost model. + bool hasTailFolded(const VPlan &Plan) const; + /// Attach the runtime checks of \p RTChecks to \p Plan. void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks, bool HasBranchWeights) const; diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 19b77e40a4103..a4aae2651ee4c 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3620,7 +3620,7 @@ std::unique_ptr LoopVectorizationPlanner::selectBestEpiloguePlan( } if (Result.Width.isScalar() || - isMoreProfitable(NextVF, Result, MaxTripCount, !CM.foldTailByMasking(), + isMoreProfitable(NextVF, Result, MaxTripCount, !hasTailFolded(MainPlan), /*IsEpilogue*/ true)) { Result = NextVF; BestPlan = &CurrentPlan; @@ -5672,7 +5672,7 @@ LoopVectorizationPlanner::precomputeCosts(VPlan &Plan, ElementCount VF, // TODO: Remove this code after stepping away from the legacy cost model and // adding code to simplify VPlans before calculating their costs. auto TC = getSmallConstantTripCount(PSE.getSE(), OrigLoop); - if (TC == VF && !CM.foldTailByMasking()) + if (TC == VF && !hasTailFolded(Plan)) addFullyUnrolledInstructionsToIgnore(OrigLoop, Legal->getInductionVars(), CostCtx.SkipCostComputation); @@ -5929,7 +5929,7 @@ DenseMap LoopVectorizationPlanner::executePlan( } if (CM.maskPartialAliasing()) { - assert(CM.foldTailByMasking() && "Expected tail folding to be enabled"); + assert(BestVPlan.hasTailFolded() && "Expected tail folding to be enabled"); RUN_VPLAN_PASS(VPlanTransforms::materializeAliasMaskCheckBlock, BestVPlan, *CM.Legal->getRuntimePointerChecking()->getDiffChecks(), HasBranchWeights); @@ -5969,6 +5969,7 @@ DenseMap LoopVectorizationPlanner::executePlan( RUN_VPLAN_PASS(VPlanTransforms::convertEVLExitCond, BestVPlan); // Regions are dissolved after optimizing for VF and UF, which completely // removes unneeded loop regions first. + const bool HasTailFolded = hasTailFolded(BestVPlan); RUN_VPLAN_PASS(VPlanTransforms::dissolveLoopRegions, BestVPlan); // Expand BranchOnTwoConds after dissolution, when latch has direct access to // its successors. @@ -5986,7 +5987,7 @@ DenseMap LoopVectorizationPlanner::executePlan( assert((OrigLoop->getUniqueLatchExitBlock() || RequiresScalarEpilogue) && "loops not exiting via the latch without required epilogue?"); VPlanTransforms::materializeVectorTripCount( - BestVPlan, VectorPH, CM.foldTailByMasking(), RequiresScalarEpilogue, + BestVPlan, VectorPH, HasTailFolded, RequiresScalarEpilogue, &BestVPlan.getVFxUF(), MaxRuntimeStep); VPlanTransforms::materializeFactors(BestVPlan, VectorPH, BestVF); // Limit expansions to VPInstruction to when not vectorizing the epilogue. @@ -6197,9 +6198,8 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(VPInstruction *VPI, : VPI->getOperand(1); if (Consecutive) { Builder.setInsertPoint(VPI); - Ptr = Builder.createConsecutiveVectorPointer( - Ptr, getLoadStoreType(I), Reverse, CM.foldTailByMasking(), - VPI->getDebugLoc()); + Ptr = Builder.createConsecutiveVectorPointer(Ptr, getLoadStoreType(I), + Reverse, VPI->getDebugLoc()); } if (Reverse && Mask) @@ -6638,8 +6638,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlan(VPlanPtr Plan, if (!RUN_VPLAN_PASS(VPlanTransforms::tryToConvertVPInstructionsToVPRecipes, *Plan, *TLI)) return nullptr; - RUN_VPLAN_PASS(VPlanTransforms::optimizeInductionLiveOutUsers, *Plan, PSE, - /*FoldTail=*/false); + RUN_VPLAN_PASS(VPlanTransforms::optimizeInductionLiveOutUsers, *Plan, PSE); return Plan; } @@ -6808,8 +6807,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlan(VPlanPtr Plan, // Optimize FindIV reductions to use sentinel-based approach when possible. RUN_VPLAN_PASS(VPlanTransforms::optimizeFindIVReductions, *Plan, PSE, *OrigLoop); - RUN_VPLAN_PASS(VPlanTransforms::optimizeInductionLiveOutUsers, *Plan, PSE, - CM.foldTailByMasking()); + RUN_VPLAN_PASS(VPlanTransforms::optimizeInductionLiveOutUsers, *Plan, PSE); // Apply mandatory transformation to handle reductions with multiple in-loop // uses if possible, bail out otherwise. @@ -7126,6 +7124,13 @@ bool LoopVectorizationPlanner::requiresScalarEpilogue(VPlan &Plan, return Result; } +bool LoopVectorizationPlanner::hasTailFolded(const VPlan &Plan) const { + bool Result = Plan.hasTailFolded(); + assert(CM.foldTailByMasking() == Result && + "CM.foldTailByMasking and the VPlan-based check must agree"); + return Result; +} + void LoopVectorizationPlanner::addMinimumIterationCheck( VPlan &Plan, ElementCount VF, unsigned UF, ElementCount MinProfitableTripCount) const { @@ -7135,7 +7140,7 @@ void LoopVectorizationPlanner::addMinimumIterationCheck( : nullptr; RUN_VPLAN_PASS(VPlanTransforms::addMinimumIterationCheck, Plan, VF, UF, MinProfitableTripCount, requiresScalarEpilogue(Plan, VF), - CM.foldTailByMasking(), OrigLoop, BranchWeights, + hasTailFolded(Plan), OrigLoop, BranchWeights, OrigLoop->getLoopPredecessor()->getTerminator()->getDebugLoc(), PSE, Plan.getEntry()); } diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 880cb87bd9923..48fb4beba6935 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -1073,7 +1073,7 @@ class BinOpSameOpcodeHelper { /// left hand side (0). static std::pair isBinOpWithConstant(const Instruction *I) { - unsigned Opcode = I->getOpcode(); + [[maybe_unused]] unsigned Opcode = I->getOpcode(); assert(binary_search(SupportedOp, Opcode) && "Unsupported opcode."); (void)SupportedOp; auto *BinOp = cast(I); diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp index 6bf257fcf8b1d..d0f8b7ad12e34 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp @@ -540,7 +540,7 @@ bool BottomUpVec::runOnRegion(Region &Rgn, const Analyses &A) { IMaps = std::make_unique(); LegalityAnalysis Legality(A.getAA(), A.getScalarEvolution(), F.getParent()->getDataLayout(), F.getContext(), - *IMaps); + *IMaps, SchedDirection::BottomUp); // TODO: Refactor to remove the unnecessary copy to SeedSliceVals. SmallVector SeedSliceVals(SeedSlice.begin(), SeedSlice.end()); diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/LoadStoreVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/LoadStoreVec.cpp index 1ce435cecdf5e..adf9ee32a3533 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/LoadStoreVec.cpp +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/LoadStoreVec.cpp @@ -71,7 +71,7 @@ bool LoadStoreVec::runOnRegion(Region &Rgn, const Analyses &A) { Function &F = *Bndl[0]->getParent()->getParent(); DL = &F.getParent()->getDataLayout(); auto &Ctx = F.getContext(); - Scheduler Sched(A.getAA(), Ctx); + Scheduler Sched(A.getAA(), Ctx, SchedDirection::BottomUp); if (!VecUtils::areConsecutive( Bndl, A.getScalarEvolution(), *DL)) return false; diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 2088f91657289..7d69b3453cba9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -1667,8 +1667,7 @@ bool LoopVectorizationPlanner::getDecisionAndClampRange( VPSingleDefRecipe * VPBuilder::createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, - bool Reverse, bool FoldTail, - DebugLoc DL) { + bool Reverse, DebugLoc DL) { VPlan &Plan = getPlan(); GEPNoWrapFlags Flags = vputils::getGEPFlagsForPtr(Ptr); if (Reverse) { @@ -1676,8 +1675,9 @@ VPBuilder::createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, // original scalar loop: drop the GEP no-wrap flags in this case. Otherwise // preserve existing flags without no-unsigned-wrap, as we will emit // negative indices. - GEPNoWrapFlags ReverseFlags = - FoldTail ? GEPNoWrapFlags::none() : Flags.withoutNoUnsignedWrap(); + GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded() + ? GEPNoWrapFlags::none() + : Flags.withoutNoUnsignedWrap(); return tryInsertInstruction(new VPVectorEndPointerRecipe( Ptr, &Plan.getVF(), SourceElementTy, /*Stride=*/-1, ReverseFlags, DL)); } diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index 3f9bb6f44497c..1ce5786793c49 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -4181,8 +4181,8 @@ class VPDerivedIVRecipe : public VPSingleDefRecipe { public: VPDerivedIVRecipe(InductionDescriptor::InductionKind Kind, - const FPMathOperator *FPBinOp, VPIRValue *Start, - VPValue *IV, VPValue *Step) + const FPMathOperator *FPBinOp, VPValue *Start, VPValue *IV, + VPValue *Step) : VPSingleDefRecipe(VPRecipeBase::VPDerivedIVSC, {Start, IV, Step}, Start->getScalarType(), nullptr), Kind(Kind), FPBinOp(FPBinOp) {} @@ -4204,7 +4204,7 @@ class VPDerivedIVRecipe : public VPSingleDefRecipe { InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override; - VPIRValue *getStartValue() const { return cast(getOperand(0)); } + VPValue *getStartValue() const { return getOperand(0); } VPValue *getIndex() const { return getOperand(1); } VPValue *getStepValue() const { return getOperand(2); } const FPMathOperator *getFPBinOp() const { return FPBinOp; } @@ -4894,6 +4894,12 @@ class VPlan { /// loop region contains a nested loop region. LLVM_ABI_FOR_TEST bool isOuterLoop() const; + /// Returns true if the vector loop region is tail-folded. + bool hasTailFolded() const { + const VPRegionBlock *LoopRegion = getVectorLoopRegion(); + return LoopRegion && LoopRegion->getHeaderMask(); + } + /// Returns the 'middle' block of the plan, that is the block that selects /// whether to execute the scalar tail loop or the exit block from the loop /// latch. If there is an early exit from the vector loop, the middle block diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 1bae8b6402932..1185b748599d1 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -1153,14 +1153,14 @@ optimizeLatchExitInductionUser(VPlan &Plan, VPValue *Op, } void VPlanTransforms::optimizeInductionLiveOutUsers( - VPlan &Plan, PredicatedScalarEvolution &PSE, bool FoldTail) { + VPlan &Plan, PredicatedScalarEvolution &PSE) { // Compute end values for all inductions. VPRegionBlock *VectorRegion = Plan.getVectorLoopRegion(); auto *VectorPH = cast(VectorRegion->getSinglePredecessor()); VPBuilder VectorPHBuilder(VectorPH, VectorPH->begin()); DenseMap EndValues; VPValue *ResumeTC = - FoldTail ? Plan.getTripCount() : &Plan.getVectorTripCount(); + Plan.hasTailFolded() ? Plan.getTripCount() : &Plan.getVectorTripCount(); for (auto &Phi : VectorRegion->getEntryBasicBlock()->phis()) { auto *WideIV = dyn_cast(&Phi); if (!WideIV) @@ -4086,7 +4086,7 @@ static void expandVPWidenPointerInduction(VPWidenPointerInductionRecipe *R) { /// Expand a VPDerivedIVRecipe into executable recipes. static void expandVPDerivedIV(VPDerivedIVRecipe *R) { VPBuilder Builder(R); - VPIRValue *Start = R->getStartValue(); + VPValue *Start = R->getStartValue(); VPValue *Step = R->getStepValue(); VPValue *Index = R->getIndex(); Type *StepTy = Step->getScalarType(); @@ -6639,6 +6639,22 @@ struct VPPartialReductionChain { VPBlendRecipe *Blend = nullptr; }; +// Return the incoming index of the single-use value in the blend, which is +// expected to be the predicated reduction update. +static std::optional +getBlendReductionUpdateValueIdx(VPBlendRecipe *Blend) { + assert(Blend && !Blend->isNormalized() && + Blend->getNumIncomingValues() == 2 && + "Expected a non-normalized blend with two incoming values"); + bool FirstIncomingHasOneUse = Blend->getIncomingValue(0)->hasOneUse(); + + // Only the update value should have one use (the blend). The previous + // value should always have at least two uses, the blend and the reduction. + if (FirstIncomingHasOneUse == Blend->getIncomingValue(1)->hasOneUse()) + return std::nullopt; + return FirstIncomingHasOneUse ? 0 : 1; +} + static VPSingleDefRecipe * optimizeExtendsForPartialReduction(VPSingleDefRecipe *Op) { // reduce.add(mul(ext(A), C)) @@ -6836,7 +6852,12 @@ static void transformToPartialReduction(const VPPartialReductionChain &Chain, m_Specific(RdxPhi)))); if (Chain.Blend) { - VPValue *BlendCond = Chain.Blend->getMask(0); + std::optional BlendReductionIdx = + getBlendReductionUpdateValueIdx(Chain.Blend); + assert(BlendReductionIdx && + Chain.Blend->getIncomingValue(*BlendReductionIdx) == WidenRecipe && + "Expected blend to contain the reduction update"); + VPValue *BlendCond = Chain.Blend->getMask(*BlendReductionIdx); Cond = ExitValue ? VPBuilder(WidenRecipe) .createLogicalAnd(Cond, BlendCond, WidenRecipe->getDebugLoc()) @@ -7084,11 +7105,17 @@ getScaledReductions(VPReductionPHIRecipe *RedPhiR) { VPValue *CurrentValue = ExitValue; while (CurrentValue != RedPhiR) { VPBlendRecipe *Blend = dyn_cast(CurrentValue); + std::optional BlendReductionIdx; if (Blend) { assert(!Blend->isNormalized() && "Expect Blend not to be normalized."); - CurrentValue = Blend->getIncomingValue(0); - if (Blend->getNumIncomingValues() != 2 || !CurrentValue->hasOneUse()) + if (Blend->getNumIncomingValues() != 2) return std::nullopt; + + BlendReductionIdx = getBlendReductionUpdateValueIdx(Blend); + if (!BlendReductionIdx) + return std::nullopt; + + CurrentValue = Blend->getIncomingValue(*BlendReductionIdx); } auto *UpdateR = dyn_cast(CurrentValue); @@ -7112,7 +7139,7 @@ getScaledReductions(VPReductionPHIRecipe *RedPhiR) { // Look for VPBlend(reduce(PrevValue, Op), PrevValue), where // reduce is equal to CurrentValue. This can be lowered as // a conditional reduction by hoisting the select to the inputs. - if (Blend && Blend->getIncomingValue(1) != PrevValue) + if (Blend && Blend->getIncomingValue(1 - *BlendReductionIdx) != PrevValue) return std::nullopt; Type *ExtSrcType = ExtendedOp->ExtendA.SrcType; diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h index 2158d6a0cc67d..85375625d34b5 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h @@ -416,8 +416,7 @@ struct VPlanTransforms { /// IV values by feeding them precomputed end values instead, possibly taken /// one step backwards. static void optimizeInductionLiveOutUsers(VPlan &Plan, - PredicatedScalarEvolution &PSE, - bool FoldTail); + PredicatedScalarEvolution &PSE); /// Add explicit broadcasts for live-ins and VPValues defined in \p Plan's entry block if they are used as vectors. static void materializeBroadcasts(VPlan &Plan); diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp index 656a5f25878df..a4d6cc0ecb480 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp @@ -334,6 +334,13 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) { break; } } + if (const auto *DIV = dyn_cast(&R)) { + if (!DIV->getStartValue()->isDefinedOutsideLoopRegions()) { + errs() << "VPDerivedIVRecipe must have start value defined outside " + "loop regions\n"; + return false; + } + } if (const auto *ScalarIVSteps = dyn_cast(&R)) { unsigned NumOps = ScalarIVSteps->getNumOperands(); if (NumOps != 3 && NumOps != 4) { diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt index 22f57a3688fc4..3cc98fdbd257d 100644 --- a/llvm/runtimes/CMakeLists.txt +++ b/llvm/runtimes/CMakeLists.txt @@ -4,6 +4,10 @@ # the two files. set(COMMON_CMAKE_ARGS "-DHAVE_LLVM_LIT=ON;-DCLANG_RESOURCE_DIR=${CLANG_RESOURCE_DIR};-DLLVM_LIBDIR_SUFFIX=${LLVM_LIBDIR_SUFFIX}") +if(APPLE AND CMAKE_OSX_SYSROOT AND (LLVM_TARGET_TRIPLE STREQUAL LLVM_HOST_TRIPLE)) + # Only propagate the host sysroot for native runtimes builds. + list(APPEND RUNTIMES_CMAKE_ARGS "-DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}") +endif() foreach(proj ${LLVM_ENABLE_RUNTIMES}) string(TOUPPER "${proj}" canon_name) STRING(REGEX REPLACE "-" "_" canon_name ${canon_name}) diff --git a/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll b/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll index 243d0df816f5e..45e19b93e41cf 100644 --- a/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll +++ b/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll @@ -308,6 +308,58 @@ define void @fshl(i32 %a, i32 %b, i32 %c, <16 x i32> %va, <16 x i32> %vb, <16 x ret void } +define void @pdep(i32 %a, i32 %b, <16 x i32> %va, <16 x i32> %vb) { +; THRU-LABEL: 'pdep' +; THRU-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) +; THRU-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) +; THRU-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void +; +; LATE-LABEL: 'pdep' +; LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) +; LATE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) +; LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; +; SIZE-LABEL: 'pdep' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) +; SIZE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; +; SIZE_LATE-LABEL: 'pdep' +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; + %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) + %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) + ret void +} + +define void @pext(i32 %a, i32 %b, <16 x i32> %va, <16 x i32> %vb) { +; THRU-LABEL: 'pext' +; THRU-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) +; THRU-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) +; THRU-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void +; +; LATE-LABEL: 'pext' +; LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) +; LATE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) +; LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; +; SIZE-LABEL: 'pext' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) +; SIZE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; +; SIZE_LATE-LABEL: 'pext' +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; + %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) + %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) + ret void +} + define void @maskedgather(<16 x ptr> %va, <16 x i1> %vb, <16 x float> %vc) { ; THRU-LABEL: 'maskedgather' ; THRU-NEXT: Cost Model: Found an estimated cost of 61 for instruction: %v = call <16 x float> @llvm.masked.gather.v16f32.v16p0(<16 x ptr> align 1 %va, <16 x i1> %vb, <16 x float> %vc) diff --git a/llvm/test/Analysis/ScalarEvolution/minmax-decomposition-guards.ll b/llvm/test/Analysis/ScalarEvolution/minmax-decomposition-guards.ll new file mode 100644 index 0000000000000..35c7790347dc7 --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/minmax-decomposition-guards.ll @@ -0,0 +1,627 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6 +; RUN: opt -disable-output -passes='print' -scalar-evolution-classify-expressions=0 %s 2>&1 | FileCheck %s + +declare void @use(i64) + +; all_of max: umax start value, every operand bounded by %bound. +define void @umax_start(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_start' +; CHECK-NEXT: Determining loop execution counts for: @umax_start +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ule i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umax_start_ne_pred(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_start_ne_pred' +; CHECK-NEXT: Determining loop execution counts for: @umax_start_ne_pred +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1)) + %bound) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1)) + %bound) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ne i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ne i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ne i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umax_start_3op(i64 %x0, i64 %x1, i64 %x2, i64 %bound) { +; CHECK-LABEL: 'umax_start_3op' +; CHECK-NEXT: Determining loop execution counts for: @umax_start_3op +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1 umax %x2)) + (%x0 umax %x1 umax %x2 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1 umax %x2)) + (%x0 umax %x1 umax %x2 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ule i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %pre.x2 = icmp ule i64 %x2, %bound + call void @llvm.assume(i1 %pre.x2) + %max01 = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + %start = call i64 @llvm.umax.i64(i64 %max01, i64 %x2) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of max, guards/condition written with operands swapped (%bound uge %x). +define void @umax_start_swapped_guards(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_start_swapped_guards' +; CHECK-NEXT: Determining loop execution counts for: @umax_start_swapped_guards +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp uge i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp uge i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ugt i64 %bound, %iv + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of max, signed. +define void @smax_start(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smax_start' +; CHECK-NEXT: Determining loop execution counts for: @smax_start +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smax %x1)) + (%x0 smax %x1 smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smax %x1)) + (%x0 smax %x1 smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sle i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.smax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smax_start_ne(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smax_start_ne' +; CHECK-NEXT: Determining loop execution counts for: @smax_start_ne +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smax %x1)) + %bound) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smax %x1)) + %bound) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ne i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ne i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.smax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp ne i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smax_start_3op(i64 %x0, i64 %x1, i64 %x2, i64 %bound) { +; CHECK-LABEL: 'smax_start_3op' +; CHECK-NEXT: Determining loop execution counts for: @smax_start_3op +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smax %x1 smax %x2)) + (%x0 smax %x1 smax %x2 smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smax %x1 smax %x2)) + (%x0 smax %x1 smax %x2 smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sle i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %pre.x2 = icmp sle i64 %x2, %bound + call void @llvm.assume(i1 %pre.x2) + %max01 = call i64 @llvm.smax.i64(i64 %x0, i64 %x1) + %start = call i64 @llvm.smax.i64(i64 %max01, i64 %x2) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of max, signed, guards/condition written with operands swapped +; (%bound sge %x). +define void @smax_start_swapped_guards(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smax_start_swapped_guards' +; CHECK-NEXT: Determining loop execution counts for: @smax_start_swapped_guards +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smax %x1)) + (%x0 smax %x1 smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smax %x1)) + (%x0 smax %x1 smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sge i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sge i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.smax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp sgt i64 %bound, %iv + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of min: umin limit, every operand bounded below by %bound (the start). +define void @umin_limit(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_limit' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ule i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_limit_ne(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_limit_ne' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit_ne +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + (%x0 umin %x1)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + (%x0 umin %x1)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ne i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ne i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ne i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_limit_3op(i64 %x0, i64 %x1, i64 %x2, i64 %bound) { +; CHECK-LABEL: 'umin_limit_3op' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit_3op +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1 umin %x2) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1 umin %x2) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ule i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %pre.x2 = icmp ule i64 %bound, %x2 + call void @llvm.assume(i1 %pre.x2) + %min01 = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + %lim = call i64 @llvm.umin.i64(i64 %min01, i64 %x2) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of min, guards/condition written with operands swapped (%x uge %bound). +define void @umin_limit_swapped_guards(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_limit_swapped_guards' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit_swapped_guards +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp uge i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp uge i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ugt i64 %lim, %iv + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of min, signed: smin limit, every operand bounded below by %bound. +define void @smin_limit(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_limit' +; CHECK-NEXT: Determining loop execution counts for: @smin_limit +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1) smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1) smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sle i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_limit_ne(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_limit_ne' +; CHECK-NEXT: Determining loop execution counts for: @smin_limit_ne +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + (%x0 smin %x1)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + (%x0 smin %x1)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ne i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ne i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp ne i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_limit_3op(i64 %x0, i64 %x1, i64 %x2, i64 %bound) { +; CHECK-LABEL: 'smin_limit_3op' +; CHECK-NEXT: Determining loop execution counts for: @smin_limit_3op +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1 smin %x2) smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1 smin %x2) smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sle i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %pre.x2 = icmp sle i64 %bound, %x2 + call void @llvm.assume(i1 %pre.x2) + %min01 = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + %lim = call i64 @llvm.smin.i64(i64 %min01, i64 %x2) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_limit_swapped_guards(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_limit_swapped_guards' +; CHECK-NEXT: Determining loop execution counts for: @smin_limit_swapped_guards +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1) smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1) smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sge i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sge i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp sgt i64 %lim, %iv + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umax_start_one_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_start_one_guard' +; CHECK-NEXT: Determining loop execution counts for: @umax_start_one_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %start = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_limit_one_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_limit_one_guard' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit_one_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %lim = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_start_no_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_start_no_guard' +; CHECK-NEXT: Determining loop execution counts for: @umin_start_no_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umin %x1)) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umin %x1)) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %start = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_start_one_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_start_one_guard' +; CHECK-NEXT: Determining loop execution counts for: @umin_start_one_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umin %x1)) + %bound) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umin %x1)) + %bound) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %start = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_start_one_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_start_one_guard' +; CHECK-NEXT: Determining loop execution counts for: @smin_start_one_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smin %x1)) + %bound) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smin %x1)) + %bound) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %start = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_start_pred_mismatch(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_start_pred_mismatch' +; CHECK-NEXT: Determining loop execution counts for: @smin_start_pred_mismatch +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smin %x1)) + ((%x0 smin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smin %x1)) + ((%x0 smin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %start = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umax_limit_no_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_limit_no_guard' +; CHECK-NEXT: Determining loop execution counts for: @umax_limit_no_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %lim = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combine-ptr-add-chain.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combine-ptr-add-chain.mir index ec64c9e02791d..bea2d7a08fd44 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combine-ptr-add-chain.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combine-ptr-add-chain.mir @@ -16,13 +16,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]](s64) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]](i64) ; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0) ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(p0) = COPY $x0 - %1:_(s64) = G_CONSTANT i64 4 - %2:_(s64) = G_CONSTANT i64 12 + %1:_(i64) = G_CONSTANT i64 4 + %2:_(i64) = G_CONSTANT i64 12 %3:_(p0) = G_PTR_ADD %0(p0), %1 %4:_(p0) = G_PTR_ADD %3(p0), %2 $x0 = COPY %4(p0) @@ -40,13 +40,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[COPY]], [[C]](s64) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[COPY]], [[C]](i64) ; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0) ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(p0) = COPY $x0 - %1:_(s64) = G_CONSTANT i64 4 - %2:_(s64) = G_CONSTANT i64 12 + %1:_(i64) = G_CONSTANT i64 4 + %2:_(i64) = G_CONSTANT i64 12 %3:_(p0) = nuw G_PTR_ADD %0(p0), %1 %4:_(p0) = nuw G_PTR_ADD %3(p0), %2 $x0 = COPY %4(p0) @@ -64,13 +64,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s64) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](i64) ; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0) ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(p0) = COPY $x0 - %1:_(s64) = G_CONSTANT i64 4 - %2:_(s64) = G_CONSTANT i64 12 + %1:_(i64) = G_CONSTANT i64 4 + %2:_(i64) = G_CONSTANT i64 12 %3:_(p0) = nuw nusw inbounds G_PTR_ADD %0(p0), %1 %4:_(p0) = nuw nusw inbounds G_PTR_ADD %3(p0), %2 $x0 = COPY %4(p0) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-and-trivial-mask.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-and-trivial-mask.mir index 1f7d5e7ed434e..5dc61236279dc 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-and-trivial-mask.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-and-trivial-mask.mir @@ -19,17 +19,17 @@ body: | ; CHECK-LABEL: name: remove_and_with_one_bit ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y - ; CHECK-NEXT: $w0 = COPY %cmp(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %cmp:_(i32) = G_ICMP intpred(eq), %x(i32), %y + ; CHECK-NEXT: $w0 = COPY %cmp(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y - %mask:_(s32) = G_CONSTANT i32 1 - %and:_(s32) = G_AND %cmp(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %cmp:_(i32) = G_ICMP intpred(eq), %x(i32), %y + %mask:_(i32) = G_CONSTANT i32 1 + %and:_(i32) = G_AND %cmp(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... @@ -44,17 +44,17 @@ body: | ; CHECK-LABEL: name: remove_and_all_ones_mask ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: $w0 = COPY %z(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: $w0 = COPY %z(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %mask:_(s32) = G_CONSTANT i32 -1 - %and:_(s32) = G_AND %z(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %mask:_(i32) = G_CONSTANT i32 -1 + %and:_(i32) = G_AND %z(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... @@ -72,19 +72,19 @@ body: | ; CHECK-LABEL: name: remove_and_all_ones_zext ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %z(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: %ext:_(i64) = G_ZEXT %z(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %ext:_(s64) = G_ZEXT %z - %mask:_(s64) = G_CONSTANT i64 4294967295 - %and:_(s64) = G_AND %ext(s64), %mask - $x0 = COPY %and(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %ext:_(i64) = G_ZEXT %z + %mask:_(i64) = G_CONSTANT i64 4294967295 + %and:_(i64) = G_AND %ext(i64), %mask + $x0 = COPY %and(i64) RET_ReallyLR implicit $x0 ... @@ -99,19 +99,19 @@ body: | ; CHECK-LABEL: name: remove_and_all_ones_anyext ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %z(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: %ext:_(i64) = G_ZEXT %z(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %ext:_(s64) = G_ZEXT %z - %mask:_(s64) = G_CONSTANT i64 4294967295 - %and:_(s64) = G_AND %ext(s64), %mask - $x0 = COPY %and(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %ext:_(i64) = G_ZEXT %z + %mask:_(i64) = G_CONSTANT i64 4294967295 + %and:_(i64) = G_AND %ext(i64), %mask + $x0 = COPY %and(i64) RET_ReallyLR implicit $x0 ... @@ -127,21 +127,21 @@ body: | ; CHECK-LABEL: name: dont_remove_all_ones_sext ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: %ext:_(s64) = G_SEXT %z(s32) - ; CHECK-NEXT: %mask:_(s64) = G_CONSTANT i64 4294967295 - ; CHECK-NEXT: %and:_(s64) = G_AND %ext, %mask - ; CHECK-NEXT: $x0 = COPY %and(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: %ext:_(i64) = G_SEXT %z(i32) + ; CHECK-NEXT: %mask:_(i64) = G_CONSTANT i64 4294967295 + ; CHECK-NEXT: %and:_(i64) = G_AND %ext, %mask + ; CHECK-NEXT: $x0 = COPY %and(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %ext:_(s64) = G_SEXT %z - %mask:_(s64) = G_CONSTANT i64 4294967295 - %and:_(s64) = G_AND %ext(s64), %mask - $x0 = COPY %and(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %ext:_(i64) = G_SEXT %z + %mask:_(i64) = G_CONSTANT i64 4294967295 + %and:_(i64) = G_AND %ext(i64), %mask + $x0 = COPY %and(i64) RET_ReallyLR implicit $x0 ... @@ -159,19 +159,19 @@ body: | ; CHECK-LABEL: name: remove_and_positive_constant_sext ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = G_CONSTANT i32 42 - ; CHECK-NEXT: %ext:_(s64) = G_SEXT %z(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = G_CONSTANT i32 42 + ; CHECK-NEXT: %ext:_(i64) = G_SEXT %z(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = G_CONSTANT i32 42 - %ext:_(s64) = G_SEXT %z - %mask:_(s64) = G_CONSTANT i64 63 - %and:_(s64) = G_AND %ext(s64), %mask - $x0 = COPY %and(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = G_CONSTANT i32 42 + %ext:_(i64) = G_SEXT %z + %mask:_(i64) = G_CONSTANT i64 63 + %and:_(i64) = G_AND %ext(i64), %mask + $x0 = COPY %and(i64) RET_ReallyLR implicit $x0 ... @@ -186,19 +186,19 @@ body: | ; CHECK-LABEL: name: not_a_mask ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y - ; CHECK-NEXT: %mask:_(s32) = G_CONSTANT i32 6 - ; CHECK-NEXT: %and:_(s32) = G_AND %cmp, %mask - ; CHECK-NEXT: $w0 = COPY %and(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %cmp:_(i32) = G_ICMP intpred(eq), %x(i32), %y + ; CHECK-NEXT: %mask:_(i32) = G_CONSTANT i32 6 + ; CHECK-NEXT: %and:_(i32) = G_AND %cmp, %mask + ; CHECK-NEXT: $w0 = COPY %and(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y - %mask:_(s32) = G_CONSTANT i32 6 - %and:_(s32) = G_AND %cmp(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %cmp:_(i32) = G_ICMP intpred(eq), %x(i32), %y + %mask:_(i32) = G_CONSTANT i32 6 + %and:_(i32) = G_AND %cmp(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... @@ -214,19 +214,19 @@ body: | ; CHECK-LABEL: name: unknown_val ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 32 - ; CHECK-NEXT: %and:_(s32) = G_AND %z, %one - ; CHECK-NEXT: $w0 = COPY %and(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: %one:_(i32) = G_CONSTANT i32 32 + ; CHECK-NEXT: %and:_(i32) = G_AND %z, %one + ; CHECK-NEXT: $w0 = COPY %and(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %one:_(s32) = G_CONSTANT i32 32 - %and:_(s32) = G_AND %z(s32), %one - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %one:_(i32) = G_CONSTANT i32 32 + %and:_(i32) = G_AND %z(i32), %one + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... --- @@ -242,15 +242,15 @@ body: | ; CHECK-LABEL: name: remove_and_assert_zext ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_zext:_(s32) = G_ASSERT_ZEXT %x, 8 - ; CHECK-NEXT: $w0 = COPY %assert_zext(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_zext:_(i32) = G_ASSERT_ZEXT %x, 8 + ; CHECK-NEXT: $w0 = COPY %assert_zext(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %assert_zext:_(s32) = G_ASSERT_ZEXT %x(s32), 8 - %mask:_(s32) = G_CONSTANT i32 255 - %and:_(s32) = G_AND %assert_zext(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %assert_zext:_(i32) = G_ASSERT_ZEXT %x(i32), 8 + %mask:_(i32) = G_CONSTANT i32 255 + %and:_(i32) = G_AND %assert_zext(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... --- @@ -265,15 +265,15 @@ body: | ; CHECK-LABEL: name: dont_remove_and_assert_zext_wrong_mask ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_zext:_(s32) = G_ASSERT_ZEXT %x, 16 - ; CHECK-NEXT: %mask:_(s32) = G_CONSTANT i32 255 - ; CHECK-NEXT: %and:_(s32) = G_AND %assert_zext, %mask - ; CHECK-NEXT: $w0 = COPY %and(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_zext:_(i32) = G_ASSERT_ZEXT %x, 16 + ; CHECK-NEXT: %mask:_(i32) = G_CONSTANT i32 255 + ; CHECK-NEXT: %and:_(i32) = G_AND %assert_zext, %mask + ; CHECK-NEXT: $w0 = COPY %and(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %assert_zext:_(s32) = G_ASSERT_ZEXT %x(s32), 16 - %mask:_(s32) = G_CONSTANT i32 255 - %and:_(s32) = G_AND %assert_zext(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %assert_zext:_(i32) = G_ASSERT_ZEXT %x(i32), 16 + %mask:_(i32) = G_CONSTANT i32 255 + %and:_(i32) = G_AND %assert_zext(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-anyext-to-zext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-anyext-to-zext.mir index 24baa2fc13317..69d2f9f0cd3bb 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-anyext-to-zext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-anyext-to-zext.mir @@ -15,17 +15,17 @@ body: | ; CHECK-LABEL: name: scalar_icmp ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(s64) = COPY $x0 - ; CHECK-NEXT: %cst_1:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %icmp:_(s32) = G_ICMP intpred(eq), %copy(s64), %cst_1 - ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %icmp(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %copy:_(i64) = COPY $x0 + ; CHECK-NEXT: %cst_1:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: %icmp:_(i32) = G_ICMP intpred(eq), %copy(i64), %cst_1 + ; CHECK-NEXT: %ext:_(i64) = G_ZEXT %icmp(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %copy:_(s64) = COPY $x0 - %cst_1:_(s64) = G_CONSTANT i64 1 - %icmp:_(s32) = G_ICMP intpred(eq), %copy(s64), %cst_1 - %ext:_(s64) = G_ANYEXT %icmp(s32) - $x0 = COPY %ext(s64) + %copy:_(i64) = COPY $x0 + %cst_1:_(i64) = G_CONSTANT i64 1 + %icmp:_(i32) = G_ICMP intpred(eq), %copy(i64), %cst_1 + %ext:_(i64) = G_ANYEXT %icmp(i32) + $x0 = COPY %ext(i64) RET_ReallyLR implicit $x0 @@ -42,19 +42,19 @@ body: | ; CHECK-LABEL: name: vector_icmp ; CHECK: liveins: $x0, $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %cst_1:_(s32) = G_CONSTANT i32 1 - ; CHECK-NEXT: %vec_cst_1:_(<2 x s32>) = G_BUILD_VECTOR %cst_1(s32), %cst_1(s32) - ; CHECK-NEXT: %icmp:_(<2 x s32>) = G_ICMP intpred(eq), %copy(<2 x s32>), %vec_cst_1 - ; CHECK-NEXT: %ext:_(<2 x s64>) = G_ANYEXT %icmp(<2 x s32>) - ; CHECK-NEXT: $q0 = COPY %ext(<2 x s64>) + ; CHECK-NEXT: %copy:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %cst_1:_(i32) = G_CONSTANT i32 1 + ; CHECK-NEXT: %vec_cst_1:_(<2 x i32>) = G_BUILD_VECTOR %cst_1(i32), %cst_1(i32) + ; CHECK-NEXT: %icmp:_(<2 x i32>) = G_ICMP intpred(eq), %copy(<2 x i32>), %vec_cst_1 + ; CHECK-NEXT: %ext:_(<2 x i64>) = G_ANYEXT %icmp(<2 x i32>) + ; CHECK-NEXT: $q0 = COPY %ext(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:_(<2 x s32>) = COPY $d0 - %cst_1:_(s32) = G_CONSTANT i32 1 - %vec_cst_1:_(<2 x s32>) = G_BUILD_VECTOR %cst_1, %cst_1 - %icmp:_(<2 x s32>) = G_ICMP intpred(eq), %copy(<2 x s32>), %vec_cst_1 - %ext:_(<2 x s64>) = G_ANYEXT %icmp(<2 x s32>) - $q0 = COPY %ext(<2 x s64>) + %copy:_(<2 x i32>) = COPY $d0 + %cst_1:_(i32) = G_CONSTANT i32 1 + %vec_cst_1:_(<2 x i32>) = G_BUILD_VECTOR %cst_1, %cst_1 + %icmp:_(<2 x i32>) = G_ICMP intpred(eq), %copy(<2 x i32>), %vec_cst_1 + %ext:_(<2 x i64>) = G_ANYEXT %icmp(<2 x i32>) + $q0 = COPY %ext(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -70,15 +70,15 @@ body: | ; CHECK-LABEL: name: scalar_fcmp ; CHECK: liveins: $x0, $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(s64) = COPY $d0 - ; CHECK-NEXT: %cst_1:_(s64) = G_FCONSTANT double 1.000000e+00 - ; CHECK-NEXT: %fcmp:_(s32) = G_FCMP intpred(eq), %copy(s64), %cst_1 - ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %fcmp(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %copy:_(f64) = COPY $d0 + ; CHECK-NEXT: %cst_1:_(f64) = G_FCONSTANT double 1.000000e+00 + ; CHECK-NEXT: %fcmp:_(i32) = G_FCMP intpred(eq), %copy(f64), %cst_1 + ; CHECK-NEXT: %ext:_(i64) = G_ZEXT %fcmp(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %copy:_(s64) = COPY $d0 - %cst_1:_(s64) = G_FCONSTANT double 1.0 - %fcmp:_(s32) = G_FCMP intpred(eq), %copy(s64), %cst_1 - %ext:_(s64) = G_ANYEXT %fcmp(s32) - $x0 = COPY %ext(s64) + %copy:_(f64) = COPY $d0 + %cst_1:_(f64) = G_FCONSTANT double 1.0 + %fcmp:_(i32) = G_FCMP intpred(eq), %copy(f64), %cst_1 + %ext:_(i64) = G_ANYEXT %fcmp(i32) + $x0 = COPY %ext(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-constant-fold.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-constant-fold.mir index 0435baaf30f01..45b503d28cabe 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-constant-fold.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-constant-fold.mir @@ -14,13 +14,13 @@ body: | ; CHECK-LABEL: name: add ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 42 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 42 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 40 - %b:_(s64) = G_CONSTANT i64 2 - %res:_(s64) = G_ADD %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 40 + %b:_(i64) = G_CONSTANT i64 2 + %res:_(i64) = G_ADD %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -37,13 +37,13 @@ body: | ; CHECK-LABEL: name: sub ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 38 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 38 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 40 - %b:_(s64) = G_CONSTANT i64 2 - %res:_(s64) = G_SUB %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 40 + %b:_(i64) = G_CONSTANT i64 2 + %res:_(i64) = G_SUB %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -60,13 +60,13 @@ body: | ; CHECK-LABEL: name: mul ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 80 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 80 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 40 - %b:_(s64) = G_CONSTANT i64 2 - %res:_(s64) = G_MUL %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 40 + %b:_(i64) = G_CONSTANT i64 2 + %res:_(i64) = G_MUL %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -83,13 +83,13 @@ body: | ; CHECK-LABEL: name: and ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 40 - %b:_(s64) = G_CONSTANT i64 2 - %res:_(s64) = G_AND %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 40 + %b:_(i64) = G_CONSTANT i64 2 + %res:_(i64) = G_AND %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -106,13 +106,13 @@ body: | ; CHECK-LABEL: name: or ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 62 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 62 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 42 - %b:_(s64) = G_CONSTANT i64 22 - %res:_(s64) = G_OR %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 42 + %b:_(i64) = G_CONSTANT i64 22 + %res:_(i64) = G_OR %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -129,13 +129,13 @@ body: | ; CHECK-LABEL: name: xor ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 12 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 12 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 8 - %b:_(s64) = G_CONSTANT i64 4 - %res:_(s64) = G_XOR %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 8 + %b:_(i64) = G_CONSTANT i64 4 + %res:_(i64) = G_XOR %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -151,13 +151,13 @@ body: | ; CHECK-LABEL: name: fadd ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double 4.200000e+01 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 4.200000e+01 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 40.0 - %b:_(s64) = G_FCONSTANT double 2.0 - %res:_(s64) = G_FADD %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 40.0 + %b:_(f64) = G_FCONSTANT double 2.0 + %res:_(f64) = G_FADD %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -173,13 +173,13 @@ body: | ; CHECK-LABEL: name: fsub ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double 3.800000e+01 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 3.800000e+01 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 40.0 - %b:_(s64) = G_FCONSTANT double 2.0 - %res:_(s64) = G_FSUB %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 40.0 + %b:_(f64) = G_FCONSTANT double 2.0 + %res:_(f64) = G_FSUB %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -195,13 +195,13 @@ body: | ; CHECK-LABEL: name: fmul ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double 8.000000e+01 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 8.000000e+01 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 40.0 - %b:_(s64) = G_FCONSTANT double 2.0 - %res:_(s64) = G_FMUL %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 40.0 + %b:_(f64) = G_FCONSTANT double 2.0 + %res:_(f64) = G_FMUL %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -217,13 +217,13 @@ body: | ; CHECK-LABEL: name: fdiv ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double 2.000000e+01 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 2.000000e+01 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 40.0 - %b:_(s64) = G_FCONSTANT double 2.0 - %res:_(s64) = G_FDIV %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 40.0 + %b:_(f64) = G_FCONSTANT double 2.0 + %res:_(f64) = G_FDIV %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -239,13 +239,13 @@ body: | ; CHECK-LABEL: name: fminimumnum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %a:_(s64) = G_FCONSTANT double 2.000000e+00 - ; CHECK-NEXT: $d0 = COPY %a(s64) + ; CHECK-NEXT: %a:_(f64) = G_FCONSTANT double 2.000000e+00 + ; CHECK-NEXT: $d0 = COPY %a(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMINIMUMNUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMINIMUMNUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -261,13 +261,13 @@ body: | ; CHECK-LABEL: name: fmaximumnum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %b:_(s64) = G_FCONSTANT double 5.000000e+00 - ; CHECK-NEXT: $d0 = COPY %b(s64) + ; CHECK-NEXT: %b:_(f64) = G_FCONSTANT double 5.000000e+00 + ; CHECK-NEXT: $d0 = COPY %b(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMAXIMUMNUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMAXIMUMNUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -284,13 +284,13 @@ body: | ; CHECK-LABEL: name: fcopysign ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double -3.000000e+00 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double -3.000000e+00 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 3.0 - %b:_(s64) = G_FCONSTANT double -1.0 - %res:_(s64) = G_FCOPYSIGN %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 3.0 + %b:_(f64) = G_FCONSTANT double -1.0 + %res:_(f64) = G_FCOPYSIGN %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -307,13 +307,13 @@ body: | ; CHECK-LABEL: name: fminnum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %a:_(s64) = G_FCONSTANT double 2.000000e+00 - ; CHECK-NEXT: $d0 = COPY %a(s64) + ; CHECK-NEXT: %a:_(f64) = G_FCONSTANT double 2.000000e+00 + ; CHECK-NEXT: $d0 = COPY %a(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMINNUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMINNUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -330,13 +330,13 @@ body: | ; CHECK-LABEL: name: fmaxnum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %b:_(s64) = G_FCONSTANT double 5.000000e+00 - ; CHECK-NEXT: $d0 = COPY %b(s64) + ; CHECK-NEXT: %b:_(f64) = G_FCONSTANT double 5.000000e+00 + ; CHECK-NEXT: $d0 = COPY %b(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMAXNUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMAXNUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -353,13 +353,13 @@ body: | ; CHECK-LABEL: name: fminimum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %a:_(s64) = G_FCONSTANT double 2.000000e+00 - ; CHECK-NEXT: $d0 = COPY %a(s64) + ; CHECK-NEXT: %a:_(f64) = G_FCONSTANT double 2.000000e+00 + ; CHECK-NEXT: $d0 = COPY %a(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMINIMUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMINIMUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -376,13 +376,13 @@ body: | ; CHECK-LABEL: name: fmaximum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %b:_(s64) = G_FCONSTANT double 5.000000e+00 - ; CHECK-NEXT: $d0 = COPY %b(s64) + ; CHECK-NEXT: %b:_(f64) = G_FCONSTANT double 5.000000e+00 + ; CHECK-NEXT: $d0 = COPY %b(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMAXIMUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMAXIMUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -398,13 +398,13 @@ body: | ; CHECK-LABEL: name: fadd32 ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s32) = G_FCONSTANT float 4.200000e+01 - ; CHECK-NEXT: $s0 = COPY %res(s32) + ; CHECK-NEXT: %res:_(i32) = G_FCONSTANT float 4.200000e+01 + ; CHECK-NEXT: $s0 = COPY %res(i32) ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %a:_(s32) = G_FCONSTANT float 40.0 - %b:_(s32) = G_FCONSTANT float 2.0 - %res:_(s32) = G_FADD %a, %b - $s0 = COPY %res(s32) + %a:_(i32) = G_FCONSTANT float 40.0 + %b:_(i32) = G_FCONSTANT float 2.0 + %res:_(i32) = G_FADD %a, %b + $s0 = COPY %res(i32) RET_ReallyLR implicit $s0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-copy-prop.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-copy-prop.mir index d867fc4341b4e..ff141a383c563 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-copy-prop.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-copy-prop.mir @@ -13,17 +13,17 @@ body: | ; CHECK-LABEL: name: postlegalize_copy_prop ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]] - ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[ADD]] - ; CHECK-NEXT: $x0 = COPY [[ADD1]](s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(i64) = COPY $x1 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(i64) = G_ADD [[COPY]], [[COPY1]] + ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(i64) = G_ADD [[ADD]], [[ADD]] + ; CHECK-NEXT: $x0 = COPY [[ADD1]](i64) ; CHECK-NEXT: RET_ReallyLR - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s64) = G_ADD %0, %1 - %3:_(s64) = COPY %2 - %4:_(s64) = G_ADD %3, %3 + %0:_(i64) = COPY $x0 + %1:_(i64) = COPY $x1 + %2:_(i64) = G_ADD %0, %1 + %3:_(i64) = COPY %2 + %4:_(i64) = G_ADD %3, %3 $x0 = COPY %4 RET_ReallyLR diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-identity.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-identity.mir index 0d36f5c8d8c03..540012453f79b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-identity.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-identity.mir @@ -14,13 +14,13 @@ body: | ; CHECK-LABEL: name: shift_of_zero ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %a:_(s64) = COPY $x0 - ; CHECK-NEXT: $x0 = COPY %a(s64) + ; CHECK-NEXT: %a:_(i64) = COPY $x0 + ; CHECK-NEXT: $x0 = COPY %a(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = COPY $x0 - %b:_(s64) = G_CONSTANT i64 0 - %res:_(s64) = G_LSHR %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = COPY $x0 + %b:_(i64) = G_CONSTANT i64 0 + %res:_(i64) = G_LSHR %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir index 9e7c573cd8a5f..041ef55fed637 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir @@ -14,13 +14,13 @@ body: | ; CHECK-LABEL: name: merge_unmerge ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(s64) = COPY $x0 - %a:_(s32), %b:_(s32) = G_UNMERGE_VALUES %0 - %merge:_(s64) = G_MERGE_VALUES %a, %b - $x0 = COPY %merge(s64) + %0:_(i64) = COPY $x0 + %a:_(i32), %b:_(i32) = G_UNMERGE_VALUES %0 + %merge:_(i64) = G_MERGE_VALUES %a, %b + $x0 = COPY %merge(i64) RET_ReallyLR implicit $x0 ... @@ -37,15 +37,15 @@ body: | ; CHECK-LABEL: name: merge_unmerge_mismatched_order ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: %b:_(s32), %a:_(s32) = G_UNMERGE_VALUES [[COPY]](s64) - ; CHECK-NEXT: %merge:_(s64) = G_MERGE_VALUES %a(s32), %b(s32) - ; CHECK-NEXT: $x0 = COPY %merge(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: %b:_(i32), %a:_(i32) = G_UNMERGE_VALUES [[COPY]](i64) + ; CHECK-NEXT: %merge:_(i64) = G_MERGE_VALUES %a(i32), %b(i32) + ; CHECK-NEXT: $x0 = COPY %merge(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(s64) = COPY $x0 - %b:_(s32), %a:_(s32) = G_UNMERGE_VALUES %0 - %merge:_(s64) = G_MERGE_VALUES %a, %b - $x0 = COPY %merge(s64) + %0:_(i64) = COPY $x0 + %b:_(i32), %a:_(i32) = G_UNMERGE_VALUES %0 + %merge:_(i64) = G_MERGE_VALUES %a, %b + $x0 = COPY %merge(i64) RET_ReallyLR implicit $x0 ... @@ -62,15 +62,15 @@ body: | ; CHECK-LABEL: name: merge_unmerge_mismatched_num_defs ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $q0 - ; CHECK-NEXT: %a:_(s32), %b:_(s32), %c:_(s32), %d:_(s32) = G_UNMERGE_VALUES [[COPY]](s128) - ; CHECK-NEXT: %merge:_(s64) = G_MERGE_VALUES %a(s32), %b(s32) - ; CHECK-NEXT: $x0 = COPY %merge(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i128) = COPY $q0 + ; CHECK-NEXT: %a:_(i32), %b:_(i32), %c:_(i32), %d:_(i32) = G_UNMERGE_VALUES [[COPY]](i128) + ; CHECK-NEXT: %merge:_(i64) = G_MERGE_VALUES %a(i32), %b(i32) + ; CHECK-NEXT: $x0 = COPY %merge(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(s128) = COPY $q0 - %a:_(s32), %b:_(s32), %c:_(s32), %d:_(s32) = G_UNMERGE_VALUES %0 - %merge:_(s64) = G_MERGE_VALUES %a, %b - $x0 = COPY %merge(s64) + %0:_(i128) = COPY $q0 + %a:_(i32), %b:_(i32), %c:_(i32), %d:_(i32) = G_UNMERGE_VALUES %0 + %merge:_(i64) = G_MERGE_VALUES %a, %b + $x0 = COPY %merge(i64) RET_ReallyLR implicit $x0 ... @@ -87,14 +87,14 @@ body: | ; CHECK-LABEL: name: merge_to_zext ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v:_(s32) = COPY $w0 - ; CHECK-NEXT: %merge:_(s64) = G_ZEXT %v(s32) - ; CHECK-NEXT: $x0 = COPY %merge(s64) + ; CHECK-NEXT: %v:_(i32) = COPY $w0 + ; CHECK-NEXT: %merge:_(i64) = G_ZEXT %v(i32) + ; CHECK-NEXT: $x0 = COPY %merge(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %v:_(s32) = COPY $w0 - %zero:_(s32) = G_CONSTANT i32 0 - %merge:_(s64) = G_MERGE_VALUES %v, %zero - $x0 = COPY %merge(s64) + %v:_(i32) = COPY $w0 + %zero:_(i32) = G_CONSTANT i32 0 + %merge:_(i64) = G_MERGE_VALUES %v, %zero + $x0 = COPY %merge(i64) RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-redundant-sextinreg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-redundant-sextinreg.mir index 5da796c637c97..90af83c768848 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-redundant-sextinreg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-redundant-sextinreg.mir @@ -14,12 +14,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %x0:_(p0) = COPY $x0 - ; CHECK-NEXT: %sextload:_(s32) = G_SEXTLOAD %x0(p0) :: (load (s16)) - ; CHECK-NEXT: $w0 = COPY %sextload(s32) + ; CHECK-NEXT: %sextload:_(i32) = G_SEXTLOAD %x0(p0) :: (load (i16)) + ; CHECK-NEXT: $w0 = COPY %sextload(i32) %x0:_(p0) = COPY $x0 - %sextload:_(s32) = G_SEXTLOAD %x0:_(p0) :: (load (s16)) - %sext_inreg:_(s32) = G_SEXT_INREG %sextload:_(s32), 24 - $w0 = COPY %sext_inreg(s32) + %sextload:_(i32) = G_SEXTLOAD %x0:_(p0) :: (load (i16)) + %sext_inreg:_(i32) = G_SEXT_INREG %sextload:_(i32), 24 + $w0 = COPY %sext_inreg(i32) ... --- name: assert_sext @@ -34,13 +34,13 @@ body: | ; CHECK-LABEL: name: assert_sext ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %w0:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 24 - ; CHECK-NEXT: $w0 = COPY %assert_sext(s32) - %w0:_(s32) = COPY $w0 - %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 24 - %sext_inreg:_(s32) = G_SEXT_INREG %assert_sext:_(s32), 24 - $w0 = COPY %sext_inreg(s32) + ; CHECK-NEXT: %w0:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 24 + ; CHECK-NEXT: $w0 = COPY %assert_sext(i32) + %w0:_(i32) = COPY $w0 + %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 24 + %sext_inreg:_(i32) = G_SEXT_INREG %assert_sext:_(i32), 24 + $w0 = COPY %sext_inreg(i32) ... --- name: assert_sext_greater_width @@ -55,14 +55,14 @@ body: | ; CHECK-LABEL: name: assert_sext_greater_width ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %w0:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 24 - ; CHECK-NEXT: %sext_inreg:_(s32) = G_SEXT_INREG %assert_sext, 12 - ; CHECK-NEXT: $w0 = COPY %sext_inreg(s32) - %w0:_(s32) = COPY $w0 - %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 24 - %sext_inreg:_(s32) = G_SEXT_INREG %assert_sext:_(s32), 12 - $w0 = COPY %sext_inreg(s32) + ; CHECK-NEXT: %w0:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 24 + ; CHECK-NEXT: %sext_inreg:_(i32) = G_SEXT_INREG %assert_sext, 12 + ; CHECK-NEXT: $w0 = COPY %sext_inreg(i32) + %w0:_(i32) = COPY $w0 + %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 24 + %sext_inreg:_(i32) = G_SEXT_INREG %assert_sext:_(i32), 12 + $w0 = COPY %sext_inreg(i32) ... --- name: assert_sext_smaller_width @@ -77,11 +77,11 @@ body: | ; CHECK-LABEL: name: assert_sext_smaller_width ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %w0:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 8 - ; CHECK-NEXT: $w0 = COPY %assert_sext(s32) - %w0:_(s32) = COPY $w0 - %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 8 - %sext_inreg:_(s32) = G_SEXT_INREG %assert_sext:_(s32), 12 - $w0 = COPY %sext_inreg(s32) + ; CHECK-NEXT: %w0:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 8 + ; CHECK-NEXT: $w0 = COPY %assert_sext(i32) + %w0:_(i32) = COPY $w0 + %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 8 + %sext_inreg:_(i32) = G_SEXT_INREG %assert_sext:_(i32), 12 + $w0 = COPY %sext_inreg(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-sameopcode-hands-crash.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-sameopcode-hands-crash.mir index 2d286ede38d5d..c9af72dab2293 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-sameopcode-hands-crash.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-sameopcode-hands-crash.mir @@ -9,22 +9,22 @@ body: | bb.1: ; CHECK-LABEL: name: crash_fn ; CHECK: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 - ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s1) = G_CONSTANT i1 false - ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[C]](p0) :: (load (s16), align 8) - ; CHECK-NEXT: [[ZEXTLOAD1:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[C]](p0) :: (load (s16)) - ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ZEXTLOAD1]], [[ZEXTLOAD]] - ; CHECK-NEXT: $w0 = COPY [[AND]](s32) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 0 + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(i1) = G_CONSTANT i1 false + ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(i32) = G_ZEXTLOAD [[C]](p0) :: (load (i16), align 8) + ; CHECK-NEXT: [[ZEXTLOAD1:%[0-9]+]]:_(i32) = G_ZEXTLOAD [[C]](p0) :: (load (i16)) + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(i32) = G_AND [[ZEXTLOAD1]], [[ZEXTLOAD]] + ; CHECK-NEXT: $w0 = COPY [[AND]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:_(p0) = G_CONSTANT i64 0 - %6:_(s32) = G_CONSTANT i32 0 - %9:_(s1) = G_CONSTANT i1 false - %0:_(s16) = G_LOAD %1(p0) :: (load (s16), align 8) - %2:_(s32) = G_ZEXT %0(s16) - %3:_(s16) = G_LOAD %1(p0) :: (load (s16)) - %4:_(s32) = G_ZEXT %3(s16) - %5:_(s32) = G_AND %4, %2 - $w0 = COPY %5(s32) + %6:_(i32) = G_CONSTANT i32 0 + %9:_(i1) = G_CONSTANT i1 false + %0:_(i16) = G_LOAD %1(p0) :: (load (i16), align 8) + %2:_(i32) = G_ZEXT %0(i16) + %3:_(i16) = G_LOAD %1(p0) :: (load (i16)) + %4:_(i32) = G_ZEXT %3(i16) + %5:_(i32) = G_AND %4, %2 + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-split-zero-stores.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-split-zero-stores.mir index 5c6f057a39317..05efb5fa4388f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-split-zero-stores.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-split-zero-stores.mir @@ -16,16 +16,16 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: %zero:_(i64) = G_CONSTANT i64 0 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 8 ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](i64) - ; CHECK-NEXT: G_STORE [[C]](i64), [[COPY]](p0) :: (store (i64), align 16) - ; CHECK-NEXT: G_STORE [[C]](i64), [[PTR_ADD]](p0) :: (store (i64) into unknown-address + 8) + ; CHECK-NEXT: G_STORE %zero(i64), [[COPY]](p0) :: (store (i64), align 16) + ; CHECK-NEXT: G_STORE %zero(i64), [[PTR_ADD]](p0) :: (store (i64) into unknown-address + 8) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s64) = G_CONSTANT i64 0 - %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %zero:_(i64) = G_CONSTANT i64 0 + %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i64>), %0(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -48,9 +48,9 @@ body: | ; CHECK-NEXT: G_STORE [[C]](i64), [[PTR_ADD]](p0) :: (store (i64) into unknown-address + 8) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s32) = G_CONSTANT i32 0 - %zerovec:_(<4 x s32>) = G_BUILD_VECTOR %zero, %zero, %zero, %zero - G_STORE %zerovec(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %zero:_(i32) = G_CONSTANT i32 0 + %zerovec:_(<4 x i32>) = G_BUILD_VECTOR %zero, %zero, %zero, %zero + G_STORE %zerovec(<4 x i32>), %0(p0) :: (store (<4 x i32>)) RET_ReallyLR ... @@ -73,9 +73,9 @@ body: | ; CHECK-NEXT: G_STORE [[C]](i64), [[PTR_ADD]](p0) :: (store (i64) into unknown-address + 8) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s16) = G_CONSTANT i16 0 - %zerovec:_(<8 x s16>) = G_BUILD_VECTOR %zero, %zero, %zero, %zero, %zero, %zero, %zero, %zero - G_STORE %zerovec(<8 x s16>), %0(p0) :: (store (<8 x s16>)) + %zero:_(i16) = G_CONSTANT i16 0 + %zerovec:_(<8 x i16>) = G_BUILD_VECTOR %zero, %zero, %zero, %zero, %zero, %zero, %zero, %zero + G_STORE %zerovec(<8 x i16>), %0(p0) :: (store (<8 x i16>)) RET_ReallyLR ... @@ -93,14 +93,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s32) = G_CONSTANT i32 0 - ; CHECK-NEXT: %zerovec:_(<2 x s32>) = G_BUILD_VECTOR %zero(s32), %zero(s32) - ; CHECK-NEXT: G_STORE %zerovec(<2 x s32>), [[COPY]](p0) :: (store (<2 x s32>)) + ; CHECK-NEXT: %zero:_(i32) = G_CONSTANT i32 0 + ; CHECK-NEXT: %zerovec:_(<2 x i32>) = G_BUILD_VECTOR %zero(i32), %zero(i32) + ; CHECK-NEXT: G_STORE %zerovec(<2 x i32>), [[COPY]](p0) :: (store (<2 x i32>)) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s32) = G_CONSTANT i32 0 - %zerovec:_(<2 x s32>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s32>), %0(p0) :: (store (<2 x s32>)) + %zero:_(i32) = G_CONSTANT i32 0 + %zerovec:_(<2 x i32>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i32>), %0(p0) :: (store (<2 x i32>)) RET_ReallyLR ... @@ -116,15 +116,15 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero(s64), %zero(s64) - ; CHECK-NEXT: G_STORE %zerovec(<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>)) - ; CHECK-NEXT: $q0 = COPY %zerovec(<2 x s64>) + ; CHECK-NEXT: %zero:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero(i64), %zero(i64) + ; CHECK-NEXT: G_STORE %zerovec(<2 x i64>), [[COPY]](p0) :: (store (<2 x i64>)) + ; CHECK-NEXT: $q0 = COPY %zerovec(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s64) = G_CONSTANT i64 0 - %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %zero:_(i64) = G_CONSTANT i64 0 + %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i64>), %0(p0) :: (store (<2 x i64>)) $q0 = COPY %zerovec RET_ReallyLR @@ -141,14 +141,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero(s64), %zero(s64) - ; CHECK-NEXT: G_STORE %zerovec(<2 x s64>), [[COPY]](p0) :: (store (<2 x s32>)) + ; CHECK-NEXT: %zero:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero(i64), %zero(i64) + ; CHECK-NEXT: G_STORE %zerovec(<2 x i64>), [[COPY]](p0) :: (store (<2 x i32>)) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s64) = G_CONSTANT i64 0 - %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s64>), %0(p0) :: (store (<2 x s32>)) + %zero:_(i64) = G_CONSTANT i64 0 + %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i64>), %0(p0) :: (store (<2 x i32>)) RET_ReallyLR ... @@ -164,14 +164,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero(s64), %zero(s64) - ; CHECK-NEXT: G_STORE %zerovec(<2 x s64>), [[COPY]](p0) :: (volatile store (<2 x s64>)) + ; CHECK-NEXT: %zero:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero(i64), %zero(i64) + ; CHECK-NEXT: G_STORE %zerovec(<2 x i64>), [[COPY]](p0) :: (volatile store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s64) = G_CONSTANT i64 0 - %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s64>), %0(p0) :: (volatile store (<2 x s64>)) + %zero:_(i64) = G_CONSTANT i64 0 + %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i64>), %0(p0) :: (volatile store (<2 x i64>)) RET_ReallyLR ... @@ -189,12 +189,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s128) = G_CONSTANT i128 0 - ; CHECK-NEXT: G_STORE %zero(s128), [[COPY]](p0) :: (store (s128)) + ; CHECK-NEXT: %zero:_(i128) = G_CONSTANT i128 0 + ; CHECK-NEXT: G_STORE %zero(i128), [[COPY]](p0) :: (store (i128)) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s128) = G_CONSTANT i128 0 - G_STORE %zero(s128), %0(p0) :: (store (s128)) + %zero:_(i128) = G_CONSTANT i128 0 + G_STORE %zero(i128), %0(p0) :: (store (i128)) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir index 085a6694995ff..bc65891cec7ce 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir @@ -18,8 +18,8 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %1:_(s32) = G_IMPLICIT_DEF - G_STORE %1(s32), %0(p0) :: (store (s32)) + %1:_(i32) = G_IMPLICIT_DEF + G_STORE %1(i32), %0(p0) :: (store (i32)) RET_ReallyLR ... @@ -34,12 +34,12 @@ body: | ; CHECK-LABEL: name: delete_add_undef ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF - ; CHECK-NEXT: $x0 = COPY [[DEF]](s64) + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(i64) = G_IMPLICIT_DEF + ; CHECK-NEXT: $x0 = COPY [[DEF]](i64) ; CHECK-NEXT: RET_ReallyLR - %0:_(s64) = COPY $x0 - %1:_(s64) = G_IMPLICIT_DEF - %add:_(s64) = G_ADD %0(s64), %1(s64) + %0:_(i64) = COPY $x0 + %1:_(i64) = G_IMPLICIT_DEF + %add:_(i64) = G_ADD %0(i64), %1(i64) $x0 = COPY %add RET_ReallyLR diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir index 1a9f8ed88ef4b..57d0e93ef4334 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir @@ -7,17 +7,17 @@ legalized: true body: | bb.1.entry: ; CHECK-LABEL: name: unmerge_dup8 - ; CHECK: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<8 x s8>) = G_DUPLANE8 [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[DUPLANE8_1:%[0-9]+]]:_(<8 x s8>) = G_DUPLANE8 [[COPY]], [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE8_]](<8 x s8>) - ; CHECK-NEXT: $d1 = COPY [[DUPLANE8_1]](<8 x s8>) + ; CHECK: [[COPY:%[0-9]+]]:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<8 x i8>) = G_DUPLANE8 [[COPY]], [[C]](i64) + ; CHECK-NEXT: [[DUPLANE8_1:%[0-9]+]]:_(<8 x i8>) = G_DUPLANE8 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE8_]](<8 x i8>) + ; CHECK-NEXT: $d1 = COPY [[DUPLANE8_1]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(<16 x s8>) = COPY $q0 - %1:_(s64) = G_CONSTANT i64 1 - %2:_(<16 x s8>) = G_DUPLANE8 %0, %1 - %3:_(<8 x s8>), %4:_(<8 x s8>) = G_UNMERGE_VALUES %2 + %0:_(<16 x i8>) = COPY $q0 + %1:_(i64) = G_CONSTANT i64 1 + %2:_(<16 x i8>) = G_DUPLANE8 %0, %1 + %3:_(<8 x i8>), %4:_(<8 x i8>) = G_UNMERGE_VALUES %2 $d0 = COPY %3 $d1 = COPY %4 RET_ReallyLR implicit $x0 @@ -29,17 +29,17 @@ legalized: true body: | bb.1.entry: ; CHECK-LABEL: name: unmerge_dup16 - ; CHECK: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<4 x s16>) = G_DUPLANE16 [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[DUPLANE16_1:%[0-9]+]]:_(<4 x s16>) = G_DUPLANE16 [[COPY]], [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE16_]](<4 x s16>) - ; CHECK-NEXT: $d1 = COPY [[DUPLANE16_1]](<4 x s16>) + ; CHECK: [[COPY:%[0-9]+]]:_(<8 x i16>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<4 x i16>) = G_DUPLANE16 [[COPY]], [[C]](i64) + ; CHECK-NEXT: [[DUPLANE16_1:%[0-9]+]]:_(<4 x i16>) = G_DUPLANE16 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE16_]](<4 x i16>) + ; CHECK-NEXT: $d1 = COPY [[DUPLANE16_1]](<4 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(<8 x s16>) = COPY $q0 - %1:_(s64) = G_CONSTANT i64 1 - %2:_(<8 x s16>) = G_DUPLANE16 %0, %1 - %3:_(<4 x s16>), %4:_(<4 x s16>) = G_UNMERGE_VALUES %2 + %0:_(<8 x i16>) = COPY $q0 + %1:_(i64) = G_CONSTANT i64 1 + %2:_(<8 x i16>) = G_DUPLANE16 %0, %1 + %3:_(<4 x i16>), %4:_(<4 x i16>) = G_UNMERGE_VALUES %2 $d0 = COPY %3 $d1 = COPY %4 RET_ReallyLR implicit $x0 @@ -51,17 +51,17 @@ legalized: true body: | bb.1.entry: ; CHECK-LABEL: name: unmerge_dup32 - ; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[DUPLANE32_1:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[COPY]], [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x s32>) - ; CHECK-NEXT: $d1 = COPY [[DUPLANE32_1]](<2 x s32>) + ; CHECK: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x i32>) = G_DUPLANE32 [[COPY]], [[C]](i64) + ; CHECK-NEXT: [[DUPLANE32_1:%[0-9]+]]:_(<2 x i32>) = G_DUPLANE32 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x i32>) + ; CHECK-NEXT: $d1 = COPY [[DUPLANE32_1]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s64) = G_CONSTANT i64 1 - %2:_(<4 x s32>) = G_DUPLANE32 %0, %1 - %3:_(<2 x s32>), %4:_(<2 x s32>) = G_UNMERGE_VALUES %2 + %0:_(<4 x i32>) = COPY $q0 + %1:_(i64) = G_CONSTANT i64 1 + %2:_(<4 x i32>) = G_DUPLANE32 %0, %1 + %3:_(<2 x i32>), %4:_(<2 x i32>) = G_UNMERGE_VALUES %2 $d0 = COPY %3 $d1 = COPY %4 RET_ReallyLR implicit $x0 @@ -73,20 +73,20 @@ legalized: true body: | bb.1.entry: ; CHECK-LABEL: name: unmerge_dup64 - ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DUPLANE64_:%[0-9]+]]:_(<2 x s64>) = G_DUPLANE64 [[COPY]], [[C]](s64) + ; CHECK: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[DUPLANE64_:%[0-9]+]]:_(<2 x i64>) = G_DUPLANE64 [[COPY]], [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[DUPLANE64_]](<2 x s64>), [[C1]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i64) = G_EXTRACT_VECTOR_ELT [[DUPLANE64_]](<2 x i64>), [[C1]](i64) ; CHECK-NEXT: [[C2:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[DUPLANE64_]](<2 x s64>), [[C2]](i64) - ; CHECK-NEXT: $d0 = COPY [[EVEC]](s64) - ; CHECK-NEXT: $d1 = COPY [[EVEC1]](s64) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(i64) = G_EXTRACT_VECTOR_ELT [[DUPLANE64_]](<2 x i64>), [[C2]](i64) + ; CHECK-NEXT: $d0 = COPY [[EVEC]](i64) + ; CHECK-NEXT: $d1 = COPY [[EVEC1]](i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(s64) = G_CONSTANT i64 1 - %2:_(<2 x s64>) = G_DUPLANE64 %0, %1 - %3:_(s64), %4:_(s64) = G_UNMERGE_VALUES %2 + %0:_(<2 x i64>) = COPY $q0 + %1:_(i64) = G_CONSTANT i64 1 + %2:_(<2 x i64>) = G_DUPLANE64 %0, %1 + %3:_(i64), %4:_(i64) = G_UNMERGE_VALUES %2 $d0 = COPY %3 $d1 = COPY %4 RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir index a86691b30f44d..56c1088c3a580 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir @@ -20,10 +20,10 @@ body: | ; LOWER-LABEL: name: slt_to_sle_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: slt_to_sle_s32 @@ -34,10 +34,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 4097 - %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 4097 + %cmp:_(i32) = G_ICMP intpred(slt), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -56,10 +56,10 @@ body: | ; LOWER-LABEL: name: slt_to_sle_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: slt_to_sle_s64 @@ -70,10 +70,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 4097 - %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 4097 + %cmp:_(i32) = G_ICMP intpred(slt), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -92,10 +92,10 @@ body: | ; LOWER-LABEL: name: sge_to_sgt_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sgt), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sge_to_sgt_s32 @@ -106,10 +106,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 4097 - %cmp:_(s32) = G_ICMP intpred(sge), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 4097 + %cmp:_(i32) = G_ICMP intpred(sge), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -128,10 +128,10 @@ body: | ; LOWER-LABEL: name: sge_to_sgt_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sgt), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sge_to_sgt_s64 @@ -142,10 +142,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 4097 - %cmp:_(s32) = G_ICMP intpred(sge), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 4097 + %cmp:_(i32) = G_ICMP intpred(sge), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -164,10 +164,10 @@ body: | ; LOWER-LABEL: name: ult_to_ule_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ule), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ule), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: ult_to_ule_s32 @@ -178,10 +178,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 4097 - %cmp:_(s32) = G_ICMP intpred(ult), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 4097 + %cmp:_(i32) = G_ICMP intpred(ult), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -200,10 +200,10 @@ body: | ; LOWER-LABEL: name: ult_to_ule_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ule), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ule), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: ult_to_ule_s64 @@ -214,10 +214,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 4097 - %cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 4097 + %cmp:_(i32) = G_ICMP intpred(ult), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -236,10 +236,10 @@ body: | ; LOWER-LABEL: name: uge_to_ugt_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ugt), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ugt), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: uge_to_ugt_s32 @@ -250,10 +250,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 4097 - %cmp:_(s32) = G_ICMP intpred(uge), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 4097 + %cmp:_(i32) = G_ICMP intpred(uge), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -272,10 +272,10 @@ body: | ; LOWER-LABEL: name: uge_to_ugt_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ugt), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ugt), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: uge_to_ugt_s64 @@ -286,10 +286,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 4097 - %cmp:_(s32) = G_ICMP intpred(uge), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 4097 + %cmp:_(i32) = G_ICMP intpred(uge), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -309,10 +309,10 @@ body: | ; LOWER-LABEL: name: sle_to_slt_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8192 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 8192 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(slt), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sle_to_slt_s32 @@ -323,10 +323,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 8191 - %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 8191 + %cmp:_(i32) = G_ICMP intpred(sle), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -345,10 +345,10 @@ body: | ; LOWER-LABEL: name: sle_to_slt_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 8192 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 8192 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(slt), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sle_to_slt_s64 @@ -359,10 +359,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 8191 - %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 8191 + %cmp:_(i32) = G_ICMP intpred(sle), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -381,10 +381,10 @@ body: | ; LOWER-LABEL: name: sgt_to_sge_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8192 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sge), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 8192 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sge), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sgt_to_sge_s32 @@ -395,10 +395,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 8191 - %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 8191 + %cmp:_(i32) = G_ICMP intpred(sgt), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -417,10 +417,10 @@ body: | ; LOWER-LABEL: name: sgt_to_sge_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 8192 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sge), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 8192 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sge), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sgt_to_sge_s64 @@ -431,10 +431,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 8191 - %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 8191 + %cmp:_(i32) = G_ICMP intpred(sgt), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -455,10 +455,10 @@ body: | ; LOWER-LABEL: name: no_opt_int32_min ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: %cst:_(s32) = G_CONSTANT i32 -2147483648 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: %cst:_(i32) = G_CONSTANT i32 -2147483648 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(slt), %reg(i32), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_int32_min @@ -470,10 +470,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 -2147483648 - %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 -2147483648 + %cmp:_(i32) = G_ICMP intpred(slt), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -494,10 +494,10 @@ body: | ; LOWER-LABEL: name: no_opt_int64_min ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: %cst:_(s64) = G_CONSTANT i64 -9223372036854775808 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: %cst:_(i64) = G_CONSTANT i64 -9223372036854775808 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(slt), %reg(i64), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_int64_min @@ -509,10 +509,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 -9223372036854775808 - %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 -9223372036854775808 + %cmp:_(i32) = G_ICMP intpred(slt), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -533,10 +533,10 @@ body: | ; LOWER-LABEL: name: no_opt_int32_max ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: %cst:_(s32) = G_CONSTANT i32 2147483647 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: %cst:_(i32) = G_CONSTANT i32 2147483647 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg(i32), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_int32_max @@ -548,10 +548,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 2147483647 - %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 2147483647 + %cmp:_(i32) = G_ICMP intpred(sle), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -573,10 +573,10 @@ body: | ; LOWER-LABEL: name: no_opt_int64_max ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: %cst:_(s64) = G_CONSTANT i64 9223372036854775807 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: %cst:_(i64) = G_CONSTANT i64 9223372036854775807 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg(i64), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_int64_max @@ -588,10 +588,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 9223372036854775807 - %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 9223372036854775807 + %cmp:_(i32) = G_ICMP intpred(sle), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -612,10 +612,10 @@ body: | ; LOWER-LABEL: name: no_opt_zero ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: %cst:_(s64) = G_CONSTANT i64 0 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: %cst:_(i64) = G_CONSTANT i64 0 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ult), %reg(i64), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_zero @@ -626,10 +626,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 0 - %cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 0 + %cmp:_(i32) = G_ICMP intpred(ult), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -647,12 +647,12 @@ body: | ; LOWER-LABEL: name: cmp_and_select ; LOWER: liveins: $w0, $w1 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg0:_(s32) = COPY $w0 - ; LOWER-NEXT: %reg1:_(s32) = COPY $w1 - ; LOWER-NEXT: %cst:_(s32) = G_CONSTANT i32 -1 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg0(s32), %cst - ; LOWER-NEXT: %select:_(s32) = G_SELECT %cmp(s32), %reg0, %reg1 - ; LOWER-NEXT: $w0 = COPY %select(s32) + ; LOWER-NEXT: %reg0:_(i32) = COPY $w0 + ; LOWER-NEXT: %reg1:_(i32) = COPY $w1 + ; LOWER-NEXT: %cst:_(i32) = G_CONSTANT i32 -1 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg0(i32), %cst + ; LOWER-NEXT: %select:_(i32) = G_SELECT %cmp(i32), %reg0, %reg1 + ; LOWER-NEXT: $w0 = COPY %select(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: cmp_and_select @@ -664,12 +664,12 @@ body: | ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 13, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %select ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg0:_(s32) = COPY $w0 - %reg1:_(s32) = COPY $w1 - %cst:_(s32) = G_CONSTANT i32 -1 - %cmp:_(s32) = G_ICMP intpred(sle), %reg0(s32), %cst - %select:_(s32) = G_SELECT %cmp, %reg0, %reg1 - $w0 = COPY %select(s32) + %reg0:_(i32) = COPY $w0 + %reg1:_(i32) = COPY $w1 + %cst:_(i32) = G_CONSTANT i32 -1 + %cmp:_(i32) = G_ICMP intpred(sle), %reg0(i32), %cst + %select:_(i32) = G_SELECT %cmp, %reg0, %reg1 + $w0 = COPY %select(i32) RET_ReallyLR implicit $w0 ... @@ -686,12 +686,12 @@ body: | ; LOWER-LABEL: name: andsxri ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg0:gpr(s64) = COPY $x0 - ; LOWER-NEXT: %bit:gpr(s64) = G_CONSTANT i64 8 - ; LOWER-NEXT: %and:gpr(s64) = G_AND %reg0, %bit - ; LOWER-NEXT: [[C:%[0-9]+]]:gpr(s64) = G_CONSTANT i64 0 - ; LOWER-NEXT: %cmp:gpr(s32) = G_ICMP intpred(sge), %and(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg0:gpr(i64) = COPY $x0 + ; LOWER-NEXT: %bit:gpr(i64) = G_CONSTANT i64 8 + ; LOWER-NEXT: %and:gpr(i64) = G_AND %reg0, %bit + ; LOWER-NEXT: [[C:%[0-9]+]]:gpr(i64) = G_CONSTANT i64 0 + ; LOWER-NEXT: %cmp:gpr(i32) = G_ICMP intpred(sge), %and(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: andsxri @@ -702,10 +702,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 4, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg0:gpr(s64) = COPY $x0 - %bit:gpr(s64) = G_CONSTANT i64 8 - %and:gpr(s64) = G_AND %reg0, %bit - %cst:gpr(s64) = G_CONSTANT i64 -1 - %cmp:gpr(s32) = G_ICMP intpred(sgt), %and(s64), %cst - $w0 = COPY %cmp(s32) + %reg0:gpr(i64) = COPY $x0 + %bit:gpr(i64) = G_CONSTANT i64 8 + %and:gpr(i64) = G_AND %reg0, %bit + %cst:gpr(i64) = G_CONSTANT i64 -1 + %cmp:gpr(i32) = G_ICMP intpred(sgt), %and(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-ext.mir index 35cc62293200b..45e7bde34661c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-ext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-ext.mir @@ -15,16 +15,16 @@ body: | ; CHECK-LABEL: name: v8s8_cst3 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<8 x s8>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<8 x i8>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 3 - ; CHECK-NEXT: %shuf:_(<8 x s8>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<8 x s8>) + ; CHECK-NEXT: %shuf:_(<8 x i8>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<8 x s8>) = COPY $d0 - %v2:_(<8 x s8>) = COPY $d1 - %shuf:_(<8 x s8>) = G_SHUFFLE_VECTOR %v1(<8 x s8>), %v2, shufflemask(3, 4, 5, 6, 7, 8, 9, 10) - $d0 = COPY %shuf(<8 x s8>) + %v1:_(<8 x i8>) = COPY $d0 + %v2:_(<8 x i8>) = COPY $d1 + %shuf:_(<8 x i8>) = G_SHUFFLE_VECTOR %v1(<8 x i8>), %v2, shufflemask(3, 4, 5, 6, 7, 8, 9, 10) + $d0 = COPY %shuf(<8 x i8>) RET_ReallyLR implicit $d0 ... --- @@ -38,16 +38,16 @@ body: | ; CHECK-LABEL: name: v8s8_cst5 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<8 x s8>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<8 x i8>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 5 - ; CHECK-NEXT: %shuf:_(<8 x s8>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<8 x s8>) + ; CHECK-NEXT: %shuf:_(<8 x i8>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<8 x s8>) = COPY $d0 - %v2:_(<8 x s8>) = COPY $d1 - %shuf:_(<8 x s8>) = G_SHUFFLE_VECTOR %v1(<8 x s8>), %v2, shufflemask(13, 14, 15, 0, 1, 2, 3, 4) - $d0 = COPY %shuf(<8 x s8>) + %v1:_(<8 x i8>) = COPY $d0 + %v2:_(<8 x i8>) = COPY $d1 + %shuf:_(<8 x i8>) = G_SHUFFLE_VECTOR %v1(<8 x i8>), %v2, shufflemask(13, 14, 15, 0, 1, 2, 3, 4) + $d0 = COPY %shuf(<8 x i8>) RET_ReallyLR implicit $d0 ... --- @@ -61,16 +61,16 @@ body: | ; CHECK-LABEL: name: v16s8_cst3 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<16 x s8>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<16 x i8>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 3 - ; CHECK-NEXT: %shuf:_(<16 x s8>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<16 x s8>) + ; CHECK-NEXT: %shuf:_(<16 x i8>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %v2:_(<16 x s8>) = COPY $q1 - %shuf:_(<16 x s8>) = G_SHUFFLE_VECTOR %v1(<16 x s8>), %v2, shufflemask(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) - $q0 = COPY %shuf(<16 x s8>) + %v1:_(<16 x i8>) = COPY $q0 + %v2:_(<16 x i8>) = COPY $q1 + %shuf:_(<16 x i8>) = G_SHUFFLE_VECTOR %v1(<16 x i8>), %v2, shufflemask(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) + $q0 = COPY %shuf(<16 x i8>) RET_ReallyLR implicit $q0 ... --- @@ -84,16 +84,16 @@ body: | ; CHECK-LABEL: name: v16s8_cst7 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<16 x s8>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<16 x i8>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 7 - ; CHECK-NEXT: %shuf:_(<16 x s8>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<16 x s8>) + ; CHECK-NEXT: %shuf:_(<16 x i8>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %v2:_(<16 x s8>) = COPY $q1 - %shuf:_(<16 x s8>) = G_SHUFFLE_VECTOR %v1(<16 x s8>), %v2, shufflemask(23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6) - $q0 = COPY %shuf(<16 x s8>) + %v1:_(<16 x i8>) = COPY $q0 + %v2:_(<16 x i8>) = COPY $q1 + %shuf:_(<16 x i8>) = G_SHUFFLE_VECTOR %v1(<16 x i8>), %v2, shufflemask(23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6) + $q0 = COPY %shuf(<16 x i8>) RET_ReallyLR implicit $q0 ... --- @@ -107,16 +107,16 @@ body: | ; CHECK-LABEL: name: v4s16_cst6 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s16>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<4 x s16>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<4 x i16>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<4 x i16>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 6 - ; CHECK-NEXT: %shuf:_(<4 x s16>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<4 x s16>) + ; CHECK-NEXT: %shuf:_(<4 x i16>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<4 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<4 x s16>) = COPY $d0 - %v2:_(<4 x s16>) = COPY $d1 - %shuf:_(<4 x s16>) = G_SHUFFLE_VECTOR %v1(<4 x s16>), %v2, shufflemask(3, 4, 5, 6) - $d0 = COPY %shuf(<4 x s16>) + %v1:_(<4 x i16>) = COPY $d0 + %v2:_(<4 x i16>) = COPY $d1 + %shuf:_(<4 x i16>) = G_SHUFFLE_VECTOR %v1(<4 x i16>), %v2, shufflemask(3, 4, 5, 6) + $d0 = COPY %shuf(<4 x i16>) RET_ReallyLR implicit $d0 ... --- @@ -130,16 +130,16 @@ body: | ; CHECK-LABEL: name: v4s32_cst12 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<4 x s32>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<4 x i32>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 12 - ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>) + ; CHECK-NEXT: %shuf:_(<4 x i32>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<4 x s32>) = COPY $q0 - %v2:_(<4 x s32>) = COPY $q1 - %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %v1(<4 x s32>), %v2, shufflemask(3, 4, 5, 6) - $q0 = COPY %shuf(<4 x s32>) + %v1:_(<4 x i32>) = COPY $q0 + %v2:_(<4 x i32>) = COPY $q1 + %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %v1(<4 x i32>), %v2, shufflemask(3, 4, 5, 6) + $q0 = COPY %shuf(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -155,16 +155,16 @@ body: | ; CHECK-LABEL: name: undef_elts_should_match_1 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<8 x s8>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<8 x i8>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 3 - ; CHECK-NEXT: %shuf:_(<8 x s8>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<8 x s8>) + ; CHECK-NEXT: %shuf:_(<8 x i8>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<8 x s8>) = COPY $d0 - %v2:_(<8 x s8>) = COPY $d1 - %shuf:_(<8 x s8>) = G_SHUFFLE_VECTOR %v1(<8 x s8>), %v2, shufflemask(3, -1, -1, 6, 7, 8, 9, 10) - $d0 = COPY %shuf(<8 x s8>) + %v1:_(<8 x i8>) = COPY $d0 + %v2:_(<8 x i8>) = COPY $d1 + %shuf:_(<8 x i8>) = G_SHUFFLE_VECTOR %v1(<8 x i8>), %v2, shufflemask(3, -1, -1, 6, 7, 8, 9, 10) + $d0 = COPY %shuf(<8 x i8>) RET_ReallyLR implicit $d0 ... --- @@ -180,16 +180,16 @@ body: | ; CHECK-LABEL: name: undef_elts_should_match_2 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<8 x s8>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<8 x i8>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 6 - ; CHECK-NEXT: %shuf:_(<8 x s8>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<8 x s8>) + ; CHECK-NEXT: %shuf:_(<8 x i8>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<8 x s8>) = COPY $d0 - %v2:_(<8 x s8>) = COPY $d1 - %shuf:_(<8 x s8>) = G_SHUFFLE_VECTOR %v1(<8 x s8>), %v2, shufflemask(-1, -1, -1, -1, 2, 3, 4, 5) - $d0 = COPY %shuf(<8 x s8>) + %v1:_(<8 x i8>) = COPY $d0 + %v2:_(<8 x i8>) = COPY $d1 + %shuf:_(<8 x i8>) = G_SHUFFLE_VECTOR %v1(<8 x i8>), %v2, shufflemask(-1, -1, -1, -1, 2, 3, 4, 5) + $d0 = COPY %shuf(<8 x i8>) RET_ReallyLR implicit $d0 ... --- @@ -205,16 +205,16 @@ body: | ; CHECK-LABEL: name: undef_elts_should_match_3 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<16 x s8>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<16 x i8>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 7 - ; CHECK-NEXT: %shuf:_(<16 x s8>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<16 x s8>) + ; CHECK-NEXT: %shuf:_(<16 x i8>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %v2:_(<16 x s8>) = COPY $q1 - %shuf:_(<16 x s8>) = G_SHUFFLE_VECTOR %v1(<16 x s8>), %v2, shufflemask(23, 24, 25, 26, -1, -1, 29, 30, 31, 0, 1, 2, 3, 4, -1, 6) - $q0 = COPY %shuf(<16 x s8>) + %v1:_(<16 x i8>) = COPY $q0 + %v2:_(<16 x i8>) = COPY $q1 + %shuf:_(<16 x i8>) = G_SHUFFLE_VECTOR %v1(<16 x i8>), %v2, shufflemask(23, 24, 25, 26, -1, -1, 29, 30, 31, 0, 1, 2, 3, 4, -1, 6) + $q0 = COPY %shuf(<16 x i8>) RET_ReallyLR implicit $q0 ... --- @@ -230,16 +230,16 @@ body: | ; CHECK-LABEL: name: undef_elts_should_match_4 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s16>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<8 x s16>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<8 x i16>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<8 x i16>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 10 - ; CHECK-NEXT: %shuf:_(<8 x s16>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<8 x s16>) + ; CHECK-NEXT: %shuf:_(<8 x i16>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<8 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<8 x s16>) = COPY $q0 - %v2:_(<8 x s16>) = COPY $q1 - %shuf:_(<8 x s16>) = G_SHUFFLE_VECTOR %v1(<8 x s16>), %v2, shufflemask(-1, -1, -1, -1, 1, 2, 3, 4) - $q0 = COPY %shuf(<8 x s16>) + %v1:_(<8 x i16>) = COPY $q0 + %v2:_(<8 x i16>) = COPY $q1 + %shuf:_(<8 x i16>) = G_SHUFFLE_VECTOR %v1(<8 x i16>), %v2, shufflemask(-1, -1, -1, -1, 1, 2, 3, 4) + $q0 = COPY %shuf(<8 x i16>) RET_ReallyLR implicit $q0 ... --- @@ -254,15 +254,15 @@ body: | ; CHECK-LABEL: name: all_undef ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s16>) = COPY $q0 + ; CHECK-NEXT: %v1:_(<8 x i16>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<8 x s16>) = G_DUPLANE16 %v1, [[C]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<8 x s16>) + ; CHECK-NEXT: %shuf:_(<8 x i16>) = G_DUPLANE16 %v1, [[C]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<8 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<8 x s16>) = COPY $q0 - %v2:_(<8 x s16>) = COPY $q1 - %shuf:_(<8 x s16>) = G_SHUFFLE_VECTOR %v1(<8 x s16>), %v2, shufflemask(-1, -1, -1, -1, -1, -1, -1, -1) - $q0 = COPY %shuf(<8 x s16>) + %v1:_(<8 x i16>) = COPY $q0 + %v2:_(<8 x i16>) = COPY $q1 + %shuf:_(<8 x i16>) = G_SHUFFLE_VECTOR %v1(<8 x i16>), %v2, shufflemask(-1, -1, -1, -1, -1, -1, -1, -1) + $q0 = COPY %shuf(<8 x i16>) RET_ReallyLR implicit $q0 ... --- @@ -276,15 +276,15 @@ body: | ; CHECK-LABEL: name: v2s64_singleton_ext ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: %v1:_(<2 x i64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 8 - ; CHECK-NEXT: %shuf:_(<2 x s64>) = G_EXT %v1, %v1, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<2 x s64>) + ; CHECK-NEXT: %shuf:_(<2 x i64>) = G_EXT %v1, %v1, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<2 x s64>) = COPY $q0 - %v2:_(<2 x s64>) = G_IMPLICIT_DEF - %shuf:_(<2 x s64>) = G_SHUFFLE_VECTOR %v1(<2 x s64>), %v2, shufflemask(1, 0) - $q0 = COPY %shuf(<2 x s64>) + %v1:_(<2 x i64>) = COPY $q0 + %v2:_(<2 x i64>) = G_IMPLICIT_DEF + %shuf:_(<2 x i64>) = G_SHUFFLE_VECTOR %v1(<2 x i64>), %v2, shufflemask(1, 0) + $q0 = COPY %shuf(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -298,15 +298,15 @@ body: | ; CHECK-LABEL: name: v2s64_singleton_ext_all_undef ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: %v1:_(<2 x i64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s64>) = G_DUPLANE64 %v1, [[C]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<2 x s64>) + ; CHECK-NEXT: %shuf:_(<2 x i64>) = G_DUPLANE64 %v1, [[C]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<2 x s64>) = COPY $q0 - %v2:_(<2 x s64>) = G_IMPLICIT_DEF - %shuf:_(<2 x s64>) = G_SHUFFLE_VECTOR %v1(<2 x s64>), %v2, shufflemask(undef, undef) - $q0 = COPY %shuf(<2 x s64>) + %v1:_(<2 x i64>) = COPY $q0 + %v2:_(<2 x i64>) = G_IMPLICIT_DEF + %shuf:_(<2 x i64>) = G_SHUFFLE_VECTOR %v1(<2 x i64>), %v2, shufflemask(undef, undef) + $q0 = COPY %shuf(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -320,14 +320,14 @@ body: | ; CHECK-LABEL: name: v2s64_singleton_ext_same ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: %v1:_(<2 x i64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %shuf:_(<2 x s64>) = G_DUPLANE64 %v1, [[C]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<2 x s64>) + ; CHECK-NEXT: %shuf:_(<2 x i64>) = G_DUPLANE64 %v1, [[C]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<2 x s64>) = COPY $q0 - %v2:_(<2 x s64>) = G_IMPLICIT_DEF - %shuf:_(<2 x s64>) = G_SHUFFLE_VECTOR %v1(<2 x s64>), %v2, shufflemask(1, 1) - $q0 = COPY %shuf(<2 x s64>) + %v1:_(<2 x i64>) = COPY $q0 + %v2:_(<2 x i64>) = G_IMPLICIT_DEF + %shuf:_(<2 x i64>) = G_SHUFFLE_VECTOR %v1(<2 x i64>), %v2, shufflemask(1, 1) + $q0 = COPY %shuf(<2 x i64>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-rev.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-rev.mir index bdd633076d49c..74e940266776c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-rev.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-rev.mir @@ -16,14 +16,14 @@ body: | ; CHECK-LABEL: name: rev64_mask_1_0 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[REV64_:%[0-9]+]]:_(<2 x s32>) = G_REV64 [[COPY]] - ; CHECK-NEXT: $d0 = COPY [[REV64_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[REV64_:%[0-9]+]]:_(<2 x i32>) = G_REV64 [[COPY]] + ; CHECK-NEXT: $d0 = COPY [[REV64_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 0) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 0) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -38,17 +38,17 @@ body: | ; CHECK-LABEL: name: rev64_mask_1_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[COPY]](<2 x s32>), [[DEF]](<2 x s32>) - ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[CONCAT_VECTORS]], [[C]](i64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x s32>) + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x i32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x i32>) = G_CONCAT_VECTORS [[COPY]](<2 x i32>), [[DEF]](<2 x i32>) + ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x i32>) = G_DUPLANE32 [[CONCAT_VECTORS]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, undef) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, undef) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -74,13 +74,13 @@ body: | ; CHECK-LABEL: name: no_rev64_mask_1 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x s32>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x i32>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 3) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 3) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-sextinreg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-sextinreg.mir index 76d4d29102cc1..65d8d96dd2e1b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-sextinreg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-sextinreg.mir @@ -10,15 +10,15 @@ body: | ; CHECK-LABEL: name: v4s32 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[C]](s32) - ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(<4 x s32>) = G_SHL %v1, [[DUP]](<4 x s32>) - ; CHECK-NEXT: %sext:_(<4 x s32>) = G_VASHR [[SHL]], 16 - ; CHECK-NEXT: $q0 = COPY %sext(<4 x s32>) + ; CHECK-NEXT: %v1:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 16 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[C]](i32) + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(<4 x i32>) = G_SHL %v1, [[DUP]](<4 x i32>) + ; CHECK-NEXT: %sext:_(<4 x i32>) = G_VASHR [[SHL]], 16 + ; CHECK-NEXT: $q0 = COPY %sext(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<4 x s32>) = COPY $q0 - %sext:_(<4 x s32>) = G_SEXT_INREG %v1, 16 + %v1:_(<4 x i32>) = COPY $q0 + %sext:_(<4 x i32>) = G_SEXT_INREG %v1, 16 $q0 = COPY %sext RET_ReallyLR implicit $q0 ... @@ -31,12 +31,12 @@ body: | ; CHECK-LABEL: name: scalar_no_lower ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(s64) = COPY $x0 - ; CHECK-NEXT: %sext:_(s64) = G_SEXT_INREG %v1, 16 - ; CHECK-NEXT: $x0 = COPY %sext(s64) + ; CHECK-NEXT: %v1:_(i64) = COPY $x0 + ; CHECK-NEXT: %sext:_(i64) = G_SEXT_INREG %v1, 16 + ; CHECK-NEXT: $x0 = COPY %sext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %v1:_(s64) = COPY $x0 - %sext:_(s64) = G_SEXT_INREG %v1, 16 + %v1:_(i64) = COPY $x0 + %sext:_(i64) = G_SEXT_INREG %v1, 16 $x0 = COPY %sext RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuf-to-ins.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuf-to-ins.mir index 31d7a3f23a127..643ad10a2ec6b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuf-to-ins.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuf-to-ins.mir @@ -22,17 +22,17 @@ body: | ; CHECK-LABEL: name: v2s32_match_left_0 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(0, 0) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(0, 0) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -52,17 +52,17 @@ body: | ; CHECK-LABEL: name: v2s32_match_left_1 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(1, 1) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(1, 1) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -82,18 +82,18 @@ body: | ; CHECK-LABEL: name: v2s32_match_left_3 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %right(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(0, 3) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(0, 3) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 @@ -114,18 +114,18 @@ body: | ; CHECK-LABEL: name: v2s32_match_right_3 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(1, 3) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(1, 3) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -145,18 +145,18 @@ body: | ; CHECK-LABEL: name: v2s32_match_right_2 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 0) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, 0) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -174,15 +174,15 @@ body: | ; CHECK-LABEL: name: dont_combine_too_many_matches_right ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 3) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, 3) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 3) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, 3) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -203,18 +203,18 @@ body: | ; CHECK-LABEL: name: tiebreaker ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %right(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 1) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, 1) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -234,18 +234,18 @@ body: | ; CHECK-LABEL: name: tiebreaker_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %right(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, -1) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, -1) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -265,18 +265,18 @@ body: | ; CHECK-LABEL: name: match_left_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %right(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(3, -1) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(3, -1) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -295,16 +295,16 @@ body: | ; CHECK-LABEL: name: match_right_undef ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %right:_(<4 x s32>) = COPY $q1 + ; CHECK-NEXT: %left:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: %right:_(<4 x i32>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 2 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<4 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<4 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 3 - ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>) + ; CHECK-NEXT: %shuf:_(<4 x i32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %left:_(<4 x s32>) = COPY $q0 - %right:_(<4 x s32>) = COPY $q1 - %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %left(<4 x s32>), %right, shufflemask(4, -1, -1, 2) - $q0 = COPY %shuf(<4 x s32>) + %left:_(<4 x i32>) = COPY $q0 + %right:_(<4 x i32>) = COPY $q1 + %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %left(<4 x i32>), %right, shufflemask(4, -1, -1, 2) + $q0 = COPY %shuf(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir index 5297ecd7019bb..a94f2ac13f3de 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir @@ -14,10 +14,10 @@ body: | ; CHECK-LABEL: name: duplane64 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DUPLANE64_:%[0-9]+]]:_(<2 x s64>) = G_DUPLANE64 [[COPY]], [[C]](i64) - ; CHECK-NEXT: $q0 = COPY [[DUPLANE64_]](<2 x s64>) + ; CHECK-NEXT: [[DUPLANE64_:%[0-9]+]]:_(<2 x i64>) = G_DUPLANE64 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUPLANE64_]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 ; ; SELECTED-LABEL: name: duplane64 @@ -27,10 +27,10 @@ body: | ; SELECTED-NEXT: [[DUPv2i64lane:%[0-9]+]]:fpr128 = DUPv2i64lane [[COPY]], 0 ; SELECTED-NEXT: $q0 = COPY [[DUPv2i64lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $q0 - %1:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0) - $q0 = COPY %4(<2 x s64>) + %1:_(<2 x i64>) = COPY $q0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(0, 0) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -46,10 +46,10 @@ body: | ; CHECK-LABEL: name: duplane32 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<4 x s32>) = G_DUPLANE32 [[COPY]], [[C]](i64) - ; CHECK-NEXT: $q0 = COPY [[DUPLANE32_]](<4 x s32>) + ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<4 x i32>) = G_DUPLANE32 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUPLANE32_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 ; ; SELECTED-LABEL: name: duplane32 @@ -59,10 +59,10 @@ body: | ; SELECTED-NEXT: [[DUPv4i32lane:%[0-9]+]]:fpr128 = DUPv4i32lane [[COPY]], 0 ; SELECTED-NEXT: $q0 = COPY [[DUPv4i32lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $q0 - %1:_(<4 x s32>) = COPY $q0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0) - $q0 = COPY %4(<4 x s32>) + %1:_(<4 x i32>) = COPY $q0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(0, 0, 0, 0) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -78,10 +78,10 @@ body: | ; CHECK-LABEL: name: duplane16 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i16>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<8 x s16>) = G_DUPLANE16 [[COPY]], [[C]](i64) - ; CHECK-NEXT: $q0 = COPY [[DUPLANE16_]](<8 x s16>) + ; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<8 x i16>) = G_DUPLANE16 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUPLANE16_]](<8 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 ; ; SELECTED-LABEL: name: duplane16 @@ -91,10 +91,10 @@ body: | ; SELECTED-NEXT: [[DUPv8i16lane:%[0-9]+]]:fpr128 = DUPv8i16lane [[COPY]], 0 ; SELECTED-NEXT: $q0 = COPY [[DUPv8i16lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $q0 - %1:_(<8 x s16>) = COPY $q0 - %2:_(<8 x s16>) = G_IMPLICIT_DEF - %4:_(<8 x s16>) = G_SHUFFLE_VECTOR %1(<8 x s16>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0) - $q0 = COPY %4(<8 x s16>) + %1:_(<8 x i16>) = COPY $q0 + %2:_(<8 x i16>) = G_IMPLICIT_DEF + %4:_(<8 x i16>) = G_SHUFFLE_VECTOR %1(<8 x i16>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0) + $q0 = COPY %4(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -110,10 +110,10 @@ body: | ; CHECK-LABEL: name: duplane8 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x i8>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<16 x s8>) = G_DUPLANE8 [[COPY]], [[C]](i64) - ; CHECK-NEXT: $q0 = COPY [[DUPLANE8_]](<16 x s8>) + ; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<16 x i8>) = G_DUPLANE8 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUPLANE8_]](<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 ; ; SELECTED-LABEL: name: duplane8 @@ -123,10 +123,10 @@ body: | ; SELECTED-NEXT: [[DUPv16i8lane:%[0-9]+]]:fpr128 = DUPv16i8lane [[COPY]], 0 ; SELECTED-NEXT: $q0 = COPY [[DUPv16i8lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $q0 - %1:_(<16 x s8>) = COPY $q0 - %2:_(<16 x s8>) = G_IMPLICIT_DEF - %4:_(<16 x s8>) = G_SHUFFLE_VECTOR %1(<16 x s8>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - $q0 = COPY %4(<16 x s8>) + %1:_(<16 x i8>) = COPY $q0 + %2:_(<16 x i8>) = G_IMPLICIT_DEF + %4:_(<16 x i8>) = G_SHUFFLE_VECTOR %1(<16 x i8>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + $q0 = COPY %4(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -148,13 +148,13 @@ body: | ; CHECK-LABEL: name: v2s32_duplane32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[COPY1]](<2 x s32>), [[DEF]](<2 x s32>) - ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[CONCAT_VECTORS]], [[C]](i64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x s32>) + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x i32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x i32>) = G_CONCAT_VECTORS [[COPY1]](<2 x i32>), [[DEF]](<2 x i32>) + ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x i32>) = G_DUPLANE32 [[CONCAT_VECTORS]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 ; ; SELECTED-LABEL: name: v2s32_duplane32 @@ -166,11 +166,11 @@ body: | ; SELECTED-NEXT: [[DUPv2i32lane:%[0-9]+]]:fpr64 = DUPv2i32lane [[INSERT_SUBREG]], 0 ; SELECTED-NEXT: $d0 = COPY [[DUPv2i32lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %3:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2, shufflemask(0, 0) - $d0 = COPY %3(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_IMPLICIT_DEF + %3:_(<2 x i32>) = G_SHUFFLE_VECTOR %1(<2 x i32>), %2, shufflemask(0, 0) + $d0 = COPY %3(<2 x i32>) RET_ReallyLR implicit $d0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir index 650a4fb8a8232..8e20fff540d4e 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir @@ -13,16 +13,16 @@ body: | ; CHECK-LABEL: name: splat_4xi32 ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s32) = COPY $w0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0) - $q0 = COPY %4(<4 x s32>) + %0:_(i32) = COPY $w0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<4 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(0, 0, 0, 0) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -38,16 +38,16 @@ body: | ; CHECK-LABEL: name: splat_2xi64 ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i64>) = G_DUP [[COPY]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $x0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s64) - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $x0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %2, %0(i64), %3(i64) + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(0, 0) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -63,16 +63,16 @@ body: | ; CHECK-LABEL: name: splat_2xi32 ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(s32) = COPY $w0 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2, shufflemask(0, 0) - $d0 = COPY %4(<2 x s32>) + %0:_(i32) = COPY $w0 + %2:_(<2 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<2 x i32>) = G_SHUFFLE_VECTOR %1(<2 x i32>), %2, shufflemask(0, 0) + $d0 = COPY %4(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -88,16 +88,16 @@ body: | ; CHECK-LABEL: name: splat_4xf32 ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $s0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s32) = COPY $s0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0) - $q0 = COPY %4(<4 x s32>) + %0:_(i32) = COPY $s0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<4 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(0, 0, 0, 0) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -113,16 +113,16 @@ body: | ; CHECK-LABEL: name: splat_2xf64 ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $d0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $d0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i64>) = G_DUP [[COPY]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $d0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s64) - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $d0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %2, %0(i64), %3(i64) + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(0, 0) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -138,16 +138,16 @@ body: | ; CHECK-LABEL: name: splat_2xf32 ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $s0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(s32) = COPY $s0 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2, shufflemask(0, 0) - $d0 = COPY %4(<2 x s32>) + %0:_(i32) = COPY $s0 + %2:_(<2 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<2 x i32>) = G_SHUFFLE_VECTOR %1(<2 x i32>), %2, shufflemask(0, 0) + $d0 = COPY %4(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -165,18 +165,18 @@ body: | ; CHECK-LABEL: name: splat_2xf64_copies ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $d0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $d0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i64>) = G_DUP [[COPY]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $d0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %6:_(<2 x s64>) = COPY %2 - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %6, %0(s64), %3(s64) - %7:_(<2 x s64>) = COPY %1 - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %7(<2 x s64>), %2, shufflemask(0, 0) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $d0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %6:_(<2 x i64>) = COPY %2 + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %6, %0(i64), %3(i64) + %7:_(<2 x i64>) = COPY %1 + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %7(<2 x i64>), %2, shufflemask(0, 0) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -192,19 +192,19 @@ body: | ; CHECK-LABEL: name: not_all_zeros ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<2 x s64>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](s64), [[C]](s64) - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY [[IVEC]](<2 x s64>) - ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x i64>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<2 x i64>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](i64), [[C]](i64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY [[IVEC]](<2 x i64>) + ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $x0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s64) - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 1) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $x0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %2, %0(i64), %3(i64) + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(0, 1) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -222,16 +222,16 @@ body: | ; CHECK-LABEL: name: all_undef ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i64>) = G_DUP [[COPY]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $x0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s64) - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(-1, -1) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $x0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %2, %0(i64), %3(i64) + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(-1, -1) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -248,16 +248,16 @@ body: | ; CHECK-LABEL: name: one_undef ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $s0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s32) = COPY $s0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, -1, 0, 0) - $q0 = COPY %4(<4 x s32>) + %0:_(i32) = COPY $s0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<4 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(0, -1, 0, 0) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -272,19 +272,19 @@ body: | ; CHECK-LABEL: name: not_all_zeros_with_undefs ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](s32), [[C]](s64) - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[IVEC]](<4 x s32>), [[DEF]], shufflemask(undef, 0, 0, 3) - ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $s0 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x i32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](i32), [[C]](i64) + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x i32>) = G_SHUFFLE_VECTOR [[IVEC]](<4 x i32>), [[DEF]], shufflemask(undef, 0, 0, 3) + ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s32) = COPY $s0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(-1, 0, 0, 3) - $q0 = COPY %4(<4 x s32>) + %0:_(i32) = COPY $s0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<4 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(-1, 0, 0, 3) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -299,16 +299,16 @@ body: | ; CHECK-LABEL: name: splat_4xi16 ; CHECK: liveins: $h0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(s16) = COPY $h0 - ; CHECK-NEXT: %splat:_(<4 x s16>) = G_DUP %copy(s16) - ; CHECK-NEXT: $d0 = COPY %splat(<4 x s16>) + ; CHECK-NEXT: %copy:_(i16) = COPY $h0 + ; CHECK-NEXT: %splat:_(<4 x i16>) = G_DUP %copy(i16) + ; CHECK-NEXT: $d0 = COPY %splat(<4 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:_(s16) = COPY $h0 - %undef:_(<4 x s16>) = G_IMPLICIT_DEF - %cst:_(s64) = G_CONSTANT i64 0 - %ins:_(<4 x s16>) = G_INSERT_VECTOR_ELT %undef, %copy(s16), %cst(s64) - %splat:_(<4 x s16>) = G_SHUFFLE_VECTOR %ins(<4 x s16>), %undef, shufflemask(0, 0, 0, 0) - $d0 = COPY %splat(<4 x s16>) + %copy:_(i16) = COPY $h0 + %undef:_(<4 x i16>) = G_IMPLICIT_DEF + %cst:_(i64) = G_CONSTANT i64 0 + %ins:_(<4 x i16>) = G_INSERT_VECTOR_ELT %undef, %copy(i16), %cst(i64) + %splat:_(<4 x i16>) = G_SHUFFLE_VECTOR %ins(<4 x i16>), %undef, shufflemask(0, 0, 0, 0) + $d0 = COPY %splat(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -323,16 +323,16 @@ body: | ; CHECK-LABEL: name: splat_8xi8 ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(s32) = COPY $w0 - ; CHECK-NEXT: %splat:_(<8 x s8>) = G_DUP %copy(s32) - ; CHECK-NEXT: $d0 = COPY %splat(<8 x s8>) + ; CHECK-NEXT: %copy:_(i32) = COPY $w0 + ; CHECK-NEXT: %splat:_(<8 x i8>) = G_DUP %copy(i32) + ; CHECK-NEXT: $d0 = COPY %splat(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:_(s32) = COPY $w0 - %undef:_(<8 x s8>) = G_IMPLICIT_DEF - %cst:_(s64) = G_CONSTANT i64 0 - %ins:_(<8 x s8>) = G_INSERT_VECTOR_ELT %undef, %copy(s32), %cst(s64) - %splat:_(<8 x s8>) = G_SHUFFLE_VECTOR %ins(<8 x s8>), %undef, shufflemask(0, 0, 0, 0, 0, 0, 0, 0) - $d0 = COPY %splat(<8 x s8>) + %copy:_(i32) = COPY $w0 + %undef:_(<8 x i8>) = G_IMPLICIT_DEF + %cst:_(i64) = G_CONSTANT i64 0 + %ins:_(<8 x i8>) = G_INSERT_VECTOR_ELT %undef, %copy(i32), %cst(i64) + %splat:_(<8 x i8>) = G_SHUFFLE_VECTOR %ins(<8 x i8>), %undef, shufflemask(0, 0, 0, 0, 0, 0, 0, 0) + $d0 = COPY %splat(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -349,32 +349,32 @@ body: | ; CHECK-LABEL: name: build_vector ; CHECK: liveins: $w0, $w1, $w2, $w3 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %lane:_(s32) = COPY $w0 - ; CHECK-NEXT: %b:_(s32) = COPY $w1 - ; CHECK-NEXT: %c:_(s32) = COPY $w2 - ; CHECK-NEXT: %d:_(s32) = COPY $w3 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %lane:_(i32) = COPY $w0 + ; CHECK-NEXT: %b:_(i32) = COPY $w1 + ; CHECK-NEXT: %c:_(i32) = COPY $w2 + ; CHECK-NEXT: %d:_(i32) = COPY $w3 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x i32>) = G_IMPLICIT_DEF ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF]], %lane(s32), [[C]](i64) + ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[DEF]], %lane(i32), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[IVEC1:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC]], %b(s32), [[C1]](i64) + ; CHECK-NEXT: [[IVEC1:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC]], %b(i32), [[C1]](i64) ; CHECK-NEXT: [[C2:%[0-9]+]]:_(i64) = G_CONSTANT i64 2 - ; CHECK-NEXT: [[IVEC2:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC1]], %c(s32), [[C2]](i64) + ; CHECK-NEXT: [[IVEC2:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC1]], %c(i32), [[C2]](i64) ; CHECK-NEXT: [[C3:%[0-9]+]]:_(i64) = G_CONSTANT i64 3 - ; CHECK-NEXT: [[IVEC3:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC2]], %d(s32), [[C3]](i64) - ; CHECK-NEXT: %buildvec:_(<4 x s32>) = COPY [[IVEC3]](<4 x s32>) + ; CHECK-NEXT: [[IVEC3:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC2]], %d(i32), [[C3]](i64) + ; CHECK-NEXT: %buildvec:_(<4 x i32>) = COPY [[IVEC3]](<4 x i32>) ; CHECK-NEXT: [[C4:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_DUPLANE32 %buildvec, [[C4]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>) + ; CHECK-NEXT: %shuf:_(<4 x i32>) = G_DUPLANE32 %buildvec, [[C4]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lane:_(s32) = COPY $w0 - %b:_(s32) = COPY $w1 - %c:_(s32) = COPY $w2 - %d:_(s32) = COPY $w3 - %undef:_(<4 x s32>) = G_IMPLICIT_DEF - %buildvec:_(<4 x s32>) = G_BUILD_VECTOR %lane, %b, %c, %d - %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec(<4 x s32>), %undef, shufflemask(0, 0, 0, 0) - $q0 = COPY %shuf(<4 x s32>) + %lane:_(i32) = COPY $w0 + %b:_(i32) = COPY $w1 + %c:_(i32) = COPY $w2 + %d:_(i32) = COPY $w3 + %undef:_(<4 x i32>) = G_IMPLICIT_DEF + %buildvec:_(<4 x i32>) = G_BUILD_VECTOR %lane, %b, %c, %d + %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %buildvec(<4 x i32>), %undef, shufflemask(0, 0, 0, 0) + $q0 = COPY %shuf(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -391,41 +391,41 @@ body: | ; CHECK-LABEL: name: build_vector_rhs ; CHECK: liveins: $w0, $w1, $w2, $w3, $w4 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %lane_0:_(s32) = COPY $w0 - ; CHECK-NEXT: %lane_1:_(s32) = COPY $w1 - ; CHECK-NEXT: %b:_(s32) = COPY $w2 - ; CHECK-NEXT: %c:_(s32) = COPY $w3 - ; CHECK-NEXT: %d:_(s32) = COPY $w4 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %lane_0:_(i32) = COPY $w0 + ; CHECK-NEXT: %lane_1:_(i32) = COPY $w1 + ; CHECK-NEXT: %b:_(i32) = COPY $w2 + ; CHECK-NEXT: %c:_(i32) = COPY $w3 + ; CHECK-NEXT: %d:_(i32) = COPY $w4 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x i32>) = G_IMPLICIT_DEF ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF]], %lane_0(s32), [[C]](i64) + ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[DEF]], %lane_0(i32), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[IVEC1:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC]], %b(s32), [[C1]](i64) + ; CHECK-NEXT: [[IVEC1:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC]], %b(i32), [[C1]](i64) ; CHECK-NEXT: [[C2:%[0-9]+]]:_(i64) = G_CONSTANT i64 2 - ; CHECK-NEXT: [[IVEC2:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC1]], %c(s32), [[C2]](i64) + ; CHECK-NEXT: [[IVEC2:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC1]], %c(i32), [[C2]](i64) ; CHECK-NEXT: [[C3:%[0-9]+]]:_(i64) = G_CONSTANT i64 3 - ; CHECK-NEXT: [[IVEC3:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC2]], %d(s32), [[C3]](i64) - ; CHECK-NEXT: %buildvec0:_(<4 x s32>) = COPY [[IVEC3]](<4 x s32>) - ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[IVEC3:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC2]], %d(i32), [[C3]](i64) + ; CHECK-NEXT: %buildvec0:_(<4 x i32>) = COPY [[IVEC3]](<4 x i32>) + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(<4 x i32>) = G_IMPLICIT_DEF ; CHECK-NEXT: [[C4:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC4:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF1]], %lane_1(s32), [[C4]](i64) + ; CHECK-NEXT: [[IVEC4:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[DEF1]], %lane_1(i32), [[C4]](i64) ; CHECK-NEXT: [[C5:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[IVEC5:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC4]], %b(s32), [[C5]](i64) + ; CHECK-NEXT: [[IVEC5:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC4]], %b(i32), [[C5]](i64) ; CHECK-NEXT: [[C6:%[0-9]+]]:_(i64) = G_CONSTANT i64 2 - ; CHECK-NEXT: [[IVEC6:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC5]], %c(s32), [[C6]](i64) + ; CHECK-NEXT: [[IVEC6:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC5]], %c(i32), [[C6]](i64) ; CHECK-NEXT: [[C7:%[0-9]+]]:_(i64) = G_CONSTANT i64 3 - ; CHECK-NEXT: [[IVEC7:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC6]], %d(s32), [[C7]](i64) - ; CHECK-NEXT: %buildvec1:_(<4 x s32>) = COPY [[IVEC7]](<4 x s32>) - ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x s32>), %buildvec1, shufflemask(4, 4, 4, 4) - ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>) + ; CHECK-NEXT: [[IVEC7:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC6]], %d(i32), [[C7]](i64) + ; CHECK-NEXT: %buildvec1:_(<4 x i32>) = COPY [[IVEC7]](<4 x i32>) + ; CHECK-NEXT: %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x i32>), %buildvec1, shufflemask(4, 4, 4, 4) + ; CHECK-NEXT: $q0 = COPY %shuf(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lane_0:_(s32) = COPY $w0 - %lane_1:_(s32) = COPY $w1 - %b:_(s32) = COPY $w2 - %c:_(s32) = COPY $w3 - %d:_(s32) = COPY $w4 - %buildvec0:_(<4 x s32>) = G_BUILD_VECTOR %lane_0(s32), %b(s32), %c(s32), %d(s32) - %buildvec1:_(<4 x s32>) = G_BUILD_VECTOR %lane_1(s32), %b(s32), %c(s32), %d(s32) - %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x s32>), %buildvec1, shufflemask(4, 4, 4, 4) - $q0 = COPY %shuf(<4 x s32>) + %lane_0:_(i32) = COPY $w0 + %lane_1:_(i32) = COPY $w1 + %b:_(i32) = COPY $w2 + %c:_(i32) = COPY $w3 + %d:_(i32) = COPY $w4 + %buildvec0:_(<4 x i32>) = G_BUILD_VECTOR %lane_0(i32), %b(i32), %c(i32), %d(i32) + %buildvec1:_(<4 x i32>) = G_BUILD_VECTOR %lane_1(i32), %b(i32), %c(i32), %d(i32) + %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x i32>), %buildvec1, shufflemask(4, 4, 4, 4) + $q0 = COPY %shuf(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-trn.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-trn.mir index cfafc68cc0073..dc73efe3f8204 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-trn.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-trn.mir @@ -17,15 +17,15 @@ body: | ; CHECK-LABEL: name: trn1_v8s8 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s8>) = COPY $d1 - ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<8 x s8>) = G_TRN1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[TRN1_]](<8 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x i8>) = COPY $d1 + ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<8 x i8>) = G_TRN1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[TRN1_]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<8 x s8>) = COPY $d0 - %1:_(<8 x s8>) = COPY $d1 - %2:_(<8 x s8>) = G_SHUFFLE_VECTOR %0(<8 x s8>), %1, shufflemask(0, 8, 2, 10, 4, 12, 6, 14) - $d0 = COPY %2(<8 x s8>) + %0:_(<8 x i8>) = COPY $d0 + %1:_(<8 x i8>) = COPY $d1 + %2:_(<8 x i8>) = G_SHUFFLE_VECTOR %0(<8 x i8>), %1, shufflemask(0, 8, 2, 10, 4, 12, 6, 14) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $q0 ... @@ -40,15 +40,15 @@ body: | ; CHECK-LABEL: name: trn2_v8s8 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s8>) = COPY $d1 - ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<8 x s8>) = G_TRN2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[TRN2_]](<8 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x i8>) = COPY $d1 + ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<8 x i8>) = G_TRN2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[TRN2_]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<8 x s8>) = COPY $d0 - %1:_(<8 x s8>) = COPY $d1 - %2:_(<8 x s8>) = G_SHUFFLE_VECTOR %0(<8 x s8>), %1, shufflemask(1, 9, 3, 11, 5, 13, 7, 15) - $d0 = COPY %2(<8 x s8>) + %0:_(<8 x i8>) = COPY $d0 + %1:_(<8 x i8>) = COPY $d1 + %2:_(<8 x i8>) = G_SHUFFLE_VECTOR %0(<8 x i8>), %1, shufflemask(1, 9, 3, 11, 5, 13, 7, 15) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $q0 ... @@ -63,15 +63,15 @@ body: | ; CHECK-LABEL: name: trn1_v16s8 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x s8>) = COPY $q1 - ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<16 x s8>) = G_TRN1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[TRN1_]](<16 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x i8>) = COPY $q1 + ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<16 x i8>) = G_TRN1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[TRN1_]](<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<16 x s8>) = COPY $q0 - %1:_(<16 x s8>) = COPY $q1 - %2:_(<16 x s8>) = G_SHUFFLE_VECTOR %0(<16 x s8>), %1, shufflemask(0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30) - $q0 = COPY %2(<16 x s8>) + %0:_(<16 x i8>) = COPY $q0 + %1:_(<16 x i8>) = COPY $q1 + %2:_(<16 x i8>) = G_SHUFFLE_VECTOR %0(<16 x i8>), %1, shufflemask(0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30) + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -86,15 +86,15 @@ body: | ; CHECK-LABEL: name: trn2_v16s8 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x s8>) = COPY $q1 - ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<16 x s8>) = G_TRN2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[TRN2_]](<16 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x i8>) = COPY $q1 + ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<16 x i8>) = G_TRN2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[TRN2_]](<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<16 x s8>) = COPY $q0 - %1:_(<16 x s8>) = COPY $q1 - %2:_(<16 x s8>) = G_SHUFFLE_VECTOR %0(<16 x s8>), %1, shufflemask(1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31) - $q0 = COPY %2(<16 x s8>) + %0:_(<16 x i8>) = COPY $q0 + %1:_(<16 x i8>) = COPY $q1 + %2:_(<16 x i8>) = G_SHUFFLE_VECTOR %0(<16 x i8>), %1, shufflemask(1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31) + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -109,15 +109,15 @@ body: | ; CHECK-LABEL: name: trn1_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<4 x s32>) = G_TRN1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[TRN1_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<4 x i32>) = G_TRN1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[TRN1_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 4, 2, 6) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 4, 2, 6) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -132,15 +132,15 @@ body: | ; CHECK-LABEL: name: trn2_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<4 x s32>) = G_TRN2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[TRN2_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<4 x i32>) = G_TRN2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[TRN2_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(1, 5, 3, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(1, 5, 3, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -156,15 +156,15 @@ body: | ; CHECK-LABEL: name: redundant_with_zip1 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x s32>) = G_ZIP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP1_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x i32>) = G_ZIP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP1_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(0, 2) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(0, 2) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -180,15 +180,15 @@ body: | ; CHECK-LABEL: name: redundant_with_zip2 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x s32>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x i32>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 3) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 3) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -204,15 +204,15 @@ body: | ; CHECK-LABEL: name: trn1_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s8>) = COPY $d1 - ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<8 x s8>) = G_TRN1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[TRN1_]](<8 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x i8>) = COPY $d1 + ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<8 x i8>) = G_TRN1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[TRN1_]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<8 x s8>) = COPY $d0 - %1:_(<8 x s8>) = COPY $d1 - %2:_(<8 x s8>) = G_SHUFFLE_VECTOR %0(<8 x s8>), %1, shufflemask(0, 8, -1, -1, 4, 12, 6, 14) - $d0 = COPY %2(<8 x s8>) + %0:_(<8 x i8>) = COPY $d0 + %1:_(<8 x i8>) = COPY $d1 + %2:_(<8 x i8>) = G_SHUFFLE_VECTOR %0(<8 x i8>), %1, shufflemask(0, 8, -1, -1, 4, 12, 6, 14) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -228,13 +228,13 @@ body: | ; CHECK-LABEL: name: trn2_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s8>) = COPY $d1 - ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<8 x s8>) = G_TRN2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[TRN2_]](<8 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x i8>) = COPY $d1 + ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<8 x i8>) = G_TRN2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[TRN2_]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<8 x s8>) = COPY $d0 - %1:_(<8 x s8>) = COPY $d1 - %2:_(<8 x s8>) = G_SHUFFLE_VECTOR %0(<8 x s8>), %1, shufflemask(1, -1, 3, 11, 5, 13, -1, -1) - $d0 = COPY %2(<8 x s8>) + %0:_(<8 x i8>) = COPY $d0 + %1:_(<8 x i8>) = COPY $d1 + %2:_(<8 x i8>) = G_SHUFFLE_VECTOR %0(<8 x i8>), %1, shufflemask(1, -1, 3, 11, 5, 13, -1, -1) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-truncstore.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-truncstore.mir index 28b55a69d3c9b..5fd4fb2fa10b7 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-truncstore.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-truncstore.mir @@ -11,12 +11,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:_(p0) = COPY $x0 - ; CHECK-NEXT: %val:_(s32) = COPY $w1 - ; CHECK-NEXT: G_STORE %val(s32), %ptr(p0) :: (store (s8)) + ; CHECK-NEXT: %val:_(i32) = COPY $w1 + ; CHECK-NEXT: G_STORE %val(i32), %ptr(p0) :: (store (i8)) %ptr:_(p0) = COPY $x0 - %val:_(s32) = COPY $w1 - %trunc:_(s8) = G_TRUNC %val - G_STORE %trunc(s8), %ptr(p0) :: (store (s8)) + %val:_(i32) = COPY $w1 + %trunc:_(i8) = G_TRUNC %val + G_STORE %trunc(i8), %ptr(p0) :: (store (i8)) ... --- name: truncstore_vector @@ -28,13 +28,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:_(p0) = COPY $x0 - ; CHECK-NEXT: %val:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %trunc:_(<4 x s8>) = G_TRUNC %val(<4 x s32>) - ; CHECK-NEXT: G_STORE %trunc(<4 x s8>), %ptr(p0) :: (store (<4 x s8>)) + ; CHECK-NEXT: %val:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: %trunc:_(<4 x i8>) = G_TRUNC %val(<4 x i32>) + ; CHECK-NEXT: G_STORE %trunc(<4 x i8>), %ptr(p0) :: (store (<4 x i8>)) %ptr:_(p0) = COPY $x0 - %val:_(<4 x s32>) = COPY $q0 - %trunc:_(<4 x s8>) = G_TRUNC %val - G_STORE %trunc(<4 x s8>), %ptr(p0) :: (store (<4 x s8>)) + %val:_(<4 x i32>) = COPY $q0 + %trunc:_(<4 x i8>) = G_TRUNC %val + G_STORE %trunc(<4 x i8>), %ptr(p0) :: (store (<4 x i8>)) ... --- name: truncstore_too_large @@ -46,11 +46,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:_(p0) = COPY $x0 - ; CHECK-NEXT: %val:_(s128) = COPY $q0 - ; CHECK-NEXT: %trunc:_(s32) = G_TRUNC %val(s128) - ; CHECK-NEXT: G_STORE %trunc(s32), %ptr(p0) :: (store (s32)) + ; CHECK-NEXT: %val:_(i128) = COPY $q0 + ; CHECK-NEXT: %trunc:_(i32) = G_TRUNC %val(i128) + ; CHECK-NEXT: G_STORE %trunc(i32), %ptr(p0) :: (store (i32)) %ptr:_(p0) = COPY $x0 - %val:_(s128) = COPY $q0 - %trunc:_(s32) = G_TRUNC %val - G_STORE %trunc(s32), %ptr(p0) :: (store (s32)) + %val:_(i128) = COPY $q0 + %trunc:_(i32) = G_TRUNC %val + G_STORE %trunc(i32), %ptr(p0) :: (store (i32)) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir index 52ef2d3578b33..24cdd6e82096b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir @@ -10,17 +10,17 @@ body: | ; CHECK-LABEL: name: v4s32 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %unmerge:_(<2 x s32>) = G_EXTRACT_SUBVECTOR %v1(<4 x s32>), 2 - ; CHECK-NEXT: %fpext:_(<2 x s64>) = G_FPEXT %unmerge(<2 x s32>) - ; CHECK-NEXT: $q0 = COPY %fpext(<2 x s64>) + ; CHECK-NEXT: %v1:_(<4 x f32>) = COPY $q0 + ; CHECK-NEXT: %unmerge:_(<2 x f32>) = G_EXTRACT_SUBVECTOR %v1(<4 x f32>), 2 + ; CHECK-NEXT: %fpext:_(<2 x f64>) = G_FPEXT %unmerge(<2 x f32>) + ; CHECK-NEXT: $q0 = COPY %fpext(<2 x f64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<4 x s32>) = COPY $q0 - %implicit:_(<4 x s32>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 8 - %ext:_(<4 x s32>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<2 x s32>), %unused:_(<2 x s32>) = G_UNMERGE_VALUES %ext:_(<4 x s32>) - %fpext:_(<2 x s64>) = G_FPEXT %unmerge:_(<2 x s32>) + %v1:_(<4 x f32>) = COPY $q0 + %implicit:_(<4 x f32>) = G_IMPLICIT_DEF + %C:_(i32) = G_CONSTANT i32 8 + %ext:_(<4 x f32>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<2 x f32>), %unused:_(<2 x f32>) = G_UNMERGE_VALUES %ext:_(<4 x f32>) + %fpext:_(<2 x f64>) = G_FPEXT %unmerge:_(<2 x f32>) $q0 = COPY %fpext RET_ReallyLR implicit $q0 ... @@ -33,40 +33,17 @@ body: | ; CHECK-LABEL: name: v8s16 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s16>) = COPY $q0 - ; CHECK-NEXT: %unmerge:_(<4 x s16>) = G_EXTRACT_SUBVECTOR %v1(<8 x s16>), 4 - ; CHECK-NEXT: %fpext:_(<4 x s32>) = G_FPEXT %unmerge(<4 x s16>) - ; CHECK-NEXT: $q0 = COPY %fpext(<4 x s32>) + ; CHECK-NEXT: %v1:_(<8 x f16>) = COPY $q0 + ; CHECK-NEXT: %unmerge:_(<4 x f16>) = G_EXTRACT_SUBVECTOR %v1(<8 x f16>), 4 + ; CHECK-NEXT: %fpext:_(<4 x f32>) = G_FPEXT %unmerge(<4 x f16>) + ; CHECK-NEXT: $q0 = COPY %fpext(<4 x f32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<8 x s16>) = COPY $q0 - %implicit:_(<8 x s16>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 8 - %ext:_(<8 x s16>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<4 x s16>), %unused:_(<4 x s16>) = G_UNMERGE_VALUES %ext:_(<8 x s16>) - %fpext:_(<4 x s32>) = G_FPEXT %unmerge:_(<4 x s16>) - $q0 = COPY %fpext - RET_ReallyLR implicit $q0 -... ---- -name: v16s8 -legalized: true -body: | - bb.0.entry: - liveins: $q0 - ; CHECK-LABEL: name: v16s8 - ; CHECK: liveins: $q0 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %v1(<16 x s8>), 8 - ; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>) - ; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>) - ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 8 - %ext:_(<16 x s8>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<8 x s8>), %unused:_(<8 x s8>) = G_UNMERGE_VALUES %ext:_(<16 x s8>) - %fpext:_(<8 x s16>) = G_FPEXT %unmerge:_(<8 x s8>) + %v1:_(<8 x f16>) = COPY $q0 + %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + %C:_(i32) = G_CONSTANT i32 8 + %ext:_(<8 x f16>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<4 x f16>), %unused:_(<4 x f16>) = G_UNMERGE_VALUES %ext:_(<8 x f16>) + %fpext:_(<4 x f32>) = G_FPEXT %unmerge:_(<4 x f16>) $q0 = COPY %fpext RET_ReallyLR implicit $q0 ... @@ -79,20 +56,20 @@ body: | ; CHECK-LABEL: name: skip_not_const ; CHECK: liveins: $q0, $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - ; CHECK-NEXT: %C:_(s32) = COPY $w0 - ; CHECK-NEXT: %ext:_(<16 x s8>) = G_EXT %v1, %implicit, %C(s32) - ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 0 - ; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>) - ; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>) + ; CHECK-NEXT: %v1:_(<8 x f16>) = COPY $q0 + ; CHECK-NEXT: %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %C:_(i32) = COPY $w0 + ; CHECK-NEXT: %ext:_(<8 x f16>) = G_EXT %v1, %implicit, %C(i32) + ; CHECK-NEXT: %unmerge:_(<4 x f16>) = G_EXTRACT_SUBVECTOR %ext(<8 x f16>), 0 + ; CHECK-NEXT: %fpext:_(<4 x f32>) = G_FPEXT %unmerge(<4 x f16>) + ; CHECK-NEXT: $q0 = COPY %fpext(<4 x f32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - %C:_(s32) = COPY $w0 - %ext:_(<16 x s8>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<8 x s8>), %unused:_(<8 x s8>) = G_UNMERGE_VALUES %ext:_(<16 x s8>) - %fpext:_(<8 x s16>) = G_FPEXT %unmerge:_(<8 x s8>) + %v1:_(<8 x f16>) = COPY $q0 + %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + %C:_(i32) = COPY $w0 + %ext:_(<8 x f16>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<4 x f16>), %unused:_(<4 x f16>) = G_UNMERGE_VALUES %ext:_(<8 x f16>) + %fpext:_(<4 x f32>) = G_FPEXT %unmerge:_(<4 x f16>) $q0 = COPY %fpext RET_ReallyLR implicit $q0 ... @@ -105,24 +82,24 @@ body: | ; CHECK-LABEL: name: skip_not_unused ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - ; CHECK-NEXT: %C:_(s32) = G_CONSTANT i32 8 - ; CHECK-NEXT: %ext:_(<16 x s8>) = G_EXT %v1, %implicit, %C(s32) - ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 0 - ; CHECK-NEXT: %unused:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 8 - ; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>) - ; CHECK-NEXT: %fpext2:_(<8 x s16>) = G_FPEXT %unused(<8 x s8>) - ; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>) - ; CHECK-NEXT: $q1 = COPY %fpext2(<8 x s16>) + ; CHECK-NEXT: %v1:_(<8 x f16>) = COPY $q0 + ; CHECK-NEXT: %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %C:_(i32) = G_CONSTANT i32 8 + ; CHECK-NEXT: %ext:_(<8 x f16>) = G_EXT %v1, %implicit, %C(i32) + ; CHECK-NEXT: %unmerge:_(<4 x f16>) = G_EXTRACT_SUBVECTOR %ext(<8 x f16>), 0 + ; CHECK-NEXT: %unused:_(<4 x f16>) = G_EXTRACT_SUBVECTOR %ext(<8 x f16>), 4 + ; CHECK-NEXT: %fpext:_(<4 x f32>) = G_FPEXT %unmerge(<4 x f16>) + ; CHECK-NEXT: %fpext2:_(<4 x f32>) = G_FPEXT %unused(<4 x f16>) + ; CHECK-NEXT: $q0 = COPY %fpext(<4 x f32>) + ; CHECK-NEXT: $q1 = COPY %fpext2(<4 x f32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 - %v1:_(<16 x s8>) = COPY $q0 - %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 8 - %ext:_(<16 x s8>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<8 x s8>), %unused:_(<8 x s8>) = G_UNMERGE_VALUES %ext:_(<16 x s8>) - %fpext:_(<8 x s16>) = G_FPEXT %unmerge:_(<8 x s8>) - %fpext2:_(<8 x s16>) = G_FPEXT %unused:_(<8 x s8>) + %v1:_(<8 x f16>) = COPY $q0 + %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + %C:_(i32) = G_CONSTANT i32 8 + %ext:_(<8 x f16>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<4 x f16>), %unused:_(<4 x f16>) = G_UNMERGE_VALUES %ext:_(<8 x f16>) + %fpext:_(<4 x f32>) = G_FPEXT %unmerge:_(<4 x f16>) + %fpext2:_(<4 x f32>) = G_FPEXT %unused:_(<4 x f16>) $q0 = COPY %fpext $q1 = COPY %fpext2 RET_ReallyLR implicit $q0, implicit $q1 @@ -136,20 +113,20 @@ body: | ; CHECK-LABEL: name: skip_borders ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %implicit:_(<4 x s32>) = G_IMPLICIT_DEF - ; CHECK-NEXT: %C:_(s32) = G_CONSTANT i32 9 - ; CHECK-NEXT: %ext:_(<4 x s32>) = G_EXT %v1, %implicit, %C(s32) - ; CHECK-NEXT: %unmerge:_(<2 x s32>) = G_EXTRACT_SUBVECTOR %ext(<4 x s32>), 0 - ; CHECK-NEXT: %fpext:_(<2 x s64>) = G_FPEXT %unmerge(<2 x s32>) - ; CHECK-NEXT: $q0 = COPY %fpext(<2 x s64>) + ; CHECK-NEXT: %v1:_(<4 x f32>) = COPY $q0 + ; CHECK-NEXT: %implicit:_(<4 x f32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %C:_(i32) = G_CONSTANT i32 9 + ; CHECK-NEXT: %ext:_(<4 x f32>) = G_EXT %v1, %implicit, %C(i32) + ; CHECK-NEXT: %unmerge:_(<2 x f32>) = G_EXTRACT_SUBVECTOR %ext(<4 x f32>), 0 + ; CHECK-NEXT: %fpext:_(<2 x f64>) = G_FPEXT %unmerge(<2 x f32>) + ; CHECK-NEXT: $q0 = COPY %fpext(<2 x f64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<4 x s32>) = COPY $q0 - %implicit:_(<4 x s32>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 9 - %ext:_(<4 x s32>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<2 x s32>), %unused:_(<2 x s32>) = G_UNMERGE_VALUES %ext:_(<4 x s32>) - %fpext:_(<2 x s64>) = G_FPEXT %unmerge:_(<2 x s32>) + %v1:_(<4 x f32>) = COPY $q0 + %implicit:_(<4 x f32>) = G_IMPLICIT_DEF + %C:_(i32) = G_CONSTANT i32 9 + %ext:_(<4 x f32>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<2 x f32>), %unused:_(<2 x f32>) = G_UNMERGE_VALUES %ext:_(<4 x f32>) + %fpext:_(<2 x f64>) = G_FPEXT %unmerge:_(<2 x f32>) $q0 = COPY %fpext RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-uzp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-uzp.mir index 00d5231cd0899..65b51bdab72ba 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-uzp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-uzp.mir @@ -18,15 +18,15 @@ body: | ; CHECK-LABEL: name: uzp1_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[UZP1_:%[0-9]+]]:_(<4 x s32>) = G_UZP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[UZP1_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[UZP1_:%[0-9]+]]:_(<4 x i32>) = G_UZP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[UZP1_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 2, 4, 6) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 2, 4, 6) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -41,15 +41,15 @@ body: | ; CHECK-LABEL: name: uzp2_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[UZP2_:%[0-9]+]]:_(<4 x s32>) = G_UZP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[UZP2_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[UZP2_:%[0-9]+]]:_(<4 x i32>) = G_UZP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[UZP2_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(1, 3, 5, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(1, 3, 5, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -66,15 +66,15 @@ body: | ; CHECK-LABEL: name: no_uzp1 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x s32>), [[COPY1]], shufflemask(0, 1, 4, 6) - ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x i32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x i32>), [[COPY1]], shufflemask(0, 1, 4, 6) + ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 1, 4, 6) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 1, 4, 6) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -91,15 +91,15 @@ body: | ; CHECK-LABEL: name: no_uzp2 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x s32>), [[COPY1]], shufflemask(1, 4, 5, 7) - ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x i32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x i32>), [[COPY1]], shufflemask(1, 4, 5, 7) + ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(1, 4, 5, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(1, 4, 5, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -116,15 +116,15 @@ body: | ; CHECK-LABEL: name: uzp1_undef ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[UZP1_:%[0-9]+]]:_(<4 x s32>) = G_UZP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[UZP1_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[UZP1_:%[0-9]+]]:_(<4 x i32>) = G_UZP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[UZP1_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, -1, 4, 6) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, -1, 4, 6) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -141,13 +141,13 @@ body: | ; CHECK-LABEL: name: uzp2_undef ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[UZP2_:%[0-9]+]]:_(<4 x s32>) = G_UZP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[UZP2_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[UZP2_:%[0-9]+]]:_(<4 x i32>) = G_UZP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[UZP2_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(1, 3, -1, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(1, 3, -1, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-vashr-vlshr.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-vashr-vlshr.mir index dfaddba5c7772..f6e2f1d9ea758 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-vashr-vlshr.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-vashr-vlshr.mir @@ -14,15 +14,15 @@ body: | ; CHECK-LABEL: name: ashr_v4s32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[VASHR:%[0-9]+]]:_(<4 x s32>) = G_VASHR [[COPY]], 5 - ; CHECK-NEXT: $q0 = COPY [[VASHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[VASHR:%[0-9]+]]:_(<4 x i32>) = G_VASHR [[COPY]], 5 + ; CHECK-NEXT: $q0 = COPY [[VASHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 5 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %1(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_ASHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 5 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %1(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_ASHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -37,15 +37,15 @@ body: | ; CHECK-LABEL: name: lshr_v4s32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[VLSHR:%[0-9]+]]:_(<4 x s32>) = G_VLSHR [[COPY]], 5 - ; CHECK-NEXT: $q0 = COPY [[VLSHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[VLSHR:%[0-9]+]]:_(<4 x i32>) = G_VLSHR [[COPY]], 5 + ; CHECK-NEXT: $q0 = COPY [[VLSHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 5 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %1(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_LSHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 5 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %1(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_LSHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -60,15 +60,15 @@ body: | ; CHECK-LABEL: name: lshr_v8s16 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0 - ; CHECK-NEXT: [[VLSHR:%[0-9]+]]:_(<8 x s16>) = G_VLSHR [[COPY]], 5 - ; CHECK-NEXT: $q0 = COPY [[VLSHR]](<8 x s16>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i16>) = COPY $q0 + ; CHECK-NEXT: [[VLSHR:%[0-9]+]]:_(<8 x i16>) = G_VLSHR [[COPY]], 5 + ; CHECK-NEXT: $q0 = COPY [[VLSHR]](<8 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<8 x s16>) = COPY $q0 - %1:_(s16) = G_CONSTANT i16 5 - %2:_(<8 x s16>) = G_BUILD_VECTOR %1(s16), %1(s16), %1(s16), %1(s16), %1(s16), %1(s16), %1(s16), %1(s16) - %3:_(<8 x s16>) = G_LSHR %0, %2(<8 x s16>) - $q0 = COPY %3(<8 x s16>) + %0:_(<8 x i16>) = COPY $q0 + %1:_(i16) = G_CONSTANT i16 5 + %2:_(<8 x i16>) = G_BUILD_VECTOR %1(i16), %1(i16), %1(i16), %1(i16), %1(i16), %1(i16), %1(i16), %1(i16) + %3:_(<8 x i16>) = G_LSHR %0, %2(<8 x i16>) + $q0 = COPY %3(<8 x i16>) RET_ReallyLR implicit $q0 ... --- @@ -83,17 +83,17 @@ body: | ; CHECK-LABEL: name: imm_too_large ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 40 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[C]](s32) - ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[COPY]], [[DUP]](<4 x s32>) - ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 40 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[C]](i32) + ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x i32>) = G_LSHR [[COPY]], [[DUP]](<4 x i32>) + ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 40 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %1(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_LSHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 40 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %1(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_LSHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -108,17 +108,17 @@ body: | ; CHECK-LABEL: name: imm_zero ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 - ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32) - ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[COPY]], [[BUILD_VECTOR]](<4 x s32>) - ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0 + ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32), [[C]](i32), [[C]](i32) + ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x i32>) = G_LSHR [[COPY]], [[BUILD_VECTOR]](<4 x i32>) + ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 0 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %1(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_LSHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 0 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %1(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_LSHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -133,18 +133,18 @@ body: | ; CHECK-LABEL: name: imm_not_splat ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 - ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 6 - ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C1]](s32), [[C]](s32), [[C]](s32) - ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[COPY]], [[BUILD_VECTOR]](<4 x s32>) - ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4 + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 6 + ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C1]](i32), [[C]](i32), [[C]](i32) + ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x i32>) = G_LSHR [[COPY]], [[BUILD_VECTOR]](<4 x i32>) + ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 4 - %4:_(s32) = G_CONSTANT i32 6 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %4(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_LSHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 4 + %4:_(i32) = G_CONSTANT i32 6 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %4(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_LSHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-zip.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-zip.mir index 5c00bfb634ef4..e0f057aa3fd94 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-zip.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-zip.mir @@ -19,15 +19,15 @@ body: | ; CHECK-LABEL: name: zip1_v2s32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x s32>) = G_ZIP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP1_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x i32>) = G_ZIP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP1_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(0, 2) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(0, 2) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -43,15 +43,15 @@ body: | ; CHECK-LABEL: name: zip1_v2s64 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1 - ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x s64>) = G_ZIP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[ZIP1_]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY $q1 + ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x i64>) = G_ZIP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[ZIP1_]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(<2 x s64>) = COPY $q1 - %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(0, 2) - $q0 = COPY %2(<2 x s64>) + %0:_(<2 x i64>) = COPY $q0 + %1:_(<2 x i64>) = COPY $q1 + %2:_(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(0, 2) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -67,15 +67,15 @@ body: | ; CHECK-LABEL: name: zip1_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<4 x s32>) = G_ZIP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[ZIP1_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<4 x i32>) = G_ZIP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[ZIP1_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 4, 1, 5) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 4, 1, 5) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -91,15 +91,15 @@ body: | ; CHECK-LABEL: name: zip2_v2s32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x s32>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x i32>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 3) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 3) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -115,15 +115,15 @@ body: | ; CHECK-LABEL: name: zip2_v2s64 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x s64>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[ZIP2_]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY $q1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x i64>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[ZIP2_]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(<2 x s64>) = COPY $q1 - %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(1, 3) - $q0 = COPY %2(<2 x s64>) + %0:_(<2 x i64>) = COPY $q0 + %1:_(<2 x i64>) = COPY $q1 + %2:_(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(1, 3) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -139,15 +139,15 @@ body: | ; CHECK-LABEL: name: zip2_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<4 x s32>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[ZIP2_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<4 x i32>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[ZIP2_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(2, 6, 3, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(2, 6, 3, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -165,16 +165,16 @@ body: | ; CHECK-LABEL: name: zip2_no_combine_idx_mismatch ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 8 - ; CHECK-NEXT: [[EXT:%[0-9]+]]:_(<2 x s64>) = G_EXT [[COPY]], [[COPY1]], [[C]](i32) - ; CHECK-NEXT: $q0 = COPY [[EXT]](<2 x s64>) + ; CHECK-NEXT: [[EXT:%[0-9]+]]:_(<2 x i64>) = G_EXT [[COPY]], [[COPY1]], [[C]](i32) + ; CHECK-NEXT: $q0 = COPY [[EXT]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(<2 x s64>) = COPY $q1 - %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(1, 2) - $q0 = COPY %2(<2 x s64>) + %0:_(<2 x i64>) = COPY $q0 + %1:_(<2 x i64>) = COPY $q1 + %2:_(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(1, 2) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -192,14 +192,14 @@ body: | ; CHECK-LABEL: name: zip1_no_combine_idx_mismatch ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY [[COPY]](<2 x s64>) - ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY [[COPY]](<2 x i64>) + ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(<2 x s64>) = COPY $q1 - %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(0, 1) - $q0 = COPY %2(<2 x s64>) + %0:_(<2 x i64>) = COPY $q0 + %1:_(<2 x i64>) = COPY $q1 + %2:_(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(0, 1) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -216,13 +216,13 @@ body: | ; CHECK-LABEL: name: no_combine_first_elt_of_mask_must_be_zero_or_one ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x s32>), [[COPY1]], shufflemask(3, 4, 1, 5) - ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x i32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x i32>), [[COPY1]], shufflemask(3, 4, 1, 5) + ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(3, 4, 1, 5) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(3, 4, 1, 5) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extending-loads.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extending-loads.mir index f4dc5ecd4e03f..565bdde81fe0d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extending-loads.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extending-loads.mir @@ -24,11 +24,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load (s8) from %ir.addr) - ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](s32) + ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(i32) = G_ZEXTLOAD [[COPY]](p0) :: (load (i8) from %ir.addr) + ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](i32) %0:_(p0) = COPY $x0 - %1:_(s8) = G_LOAD %0 :: (load (s8) from %ir.addr) - %2:_(s32) = G_ZEXT %1 + %1:_(i8) = G_LOAD %0 :: (load (i8) from %ir.addr) + %2:_(i32) = G_ZEXT %1 $w0 = COPY %2 ... @@ -42,10 +42,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[COPY]](p0) :: (load (s32) from %ir.addr) - ; CHECK-NEXT: $x0 = COPY [[LOAD]](s64) + ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(i64) = G_LOAD [[COPY]](p0) :: (load (i32) from %ir.addr) + ; CHECK-NEXT: $x0 = COPY [[LOAD]](i64) %0:_(p0) = COPY $x0 - %1:_(s32) = G_LOAD %0 :: (load (s32) from %ir.addr) - %2:_(s64) = G_ANYEXT %1 + %1:_(i32) = G_LOAD %0 :: (load (i32) from %ir.addr) + %2:_(i64) = G_ANYEXT %1 $x0 = COPY %2 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extractvec-faddp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extractvec-faddp.mir index 819a81a472788..8d659c00ce8dc 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extractvec-faddp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extractvec-faddp.mir @@ -14,21 +14,21 @@ body: | ; CHECK-LABEL: name: f64_faddp ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s64>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f64>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s64>), [[C1]](i64) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[EVEC]], [[EVEC1]] - ; CHECK-NEXT: $d0 = COPY [[FADD]](s64) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f64>), [[C1]](i64) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(f64) = G_FADD [[EVEC]], [[EVEC1]] + ; CHECK-NEXT: $d0 = COPY [[FADD]](f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(1, undef) - %3:_(<2 x s64>) = G_FADD %1, %0 - %4:_(s64) = G_EXTRACT_VECTOR_ELT %3(<2 x s64>), %5(s64) - $d0 = COPY %4(s64) + %0:_(<2 x f64>) = COPY $q0 + %2:_(<2 x f64>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f64>) = G_SHUFFLE_VECTOR %0(<2 x f64>), %2, shufflemask(1, undef) + %3:_(<2 x f64>) = G_FADD %1, %0 + %4:_(f64) = G_EXTRACT_VECTOR_ELT %3(<2 x f64>), %5(i64) + $d0 = COPY %4(f64) RET_ReallyLR implicit $d0 ... @@ -46,21 +46,21 @@ body: | ; CHECK-LABEL: name: f64_faddp_commuted ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s64>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f64>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s64>), [[C1]](i64) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[EVEC]], [[EVEC1]] - ; CHECK-NEXT: $d0 = COPY [[FADD]](s64) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f64>), [[C1]](i64) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(f64) = G_FADD [[EVEC]], [[EVEC1]] + ; CHECK-NEXT: $d0 = COPY [[FADD]](f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(1, undef) - %3:_(<2 x s64>) = G_FADD %0, %1 - %4:_(s64) = G_EXTRACT_VECTOR_ELT %3(<2 x s64>), %5(s64) - $d0 = COPY %4(s64) + %0:_(<2 x f64>) = COPY $q0 + %2:_(<2 x f64>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f64>) = G_SHUFFLE_VECTOR %0(<2 x f64>), %2, shufflemask(1, undef) + %3:_(<2 x f64>) = G_FADD %0, %1 + %4:_(f64) = G_EXTRACT_VECTOR_ELT %3(<2 x f64>), %5(i64) + $d0 = COPY %4(f64) RET_ReallyLR implicit $d0 ... @@ -78,21 +78,21 @@ body: | ; CHECK-LABEL: name: f32_faddp ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C1]](i64) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s32) = G_FADD [[EVEC]], [[EVEC1]] - ; CHECK-NEXT: $s0 = COPY [[FADD]](s32) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(f32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f32>), [[C1]](i64) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[EVEC]], [[EVEC1]] + ; CHECK-NEXT: $s0 = COPY [[FADD]](f32) ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:_(<2 x s32>) = COPY $d0 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, undef) - %3:_(<2 x s32>) = G_FADD %1, %0 - %4:_(s32) = G_EXTRACT_VECTOR_ELT %3(<2 x s32>), %5(s64) - $s0 = COPY %4(s32) + %0:_(<2 x f32>) = COPY $d0 + %2:_(<2 x f32>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f32>) = G_SHUFFLE_VECTOR %0(<2 x f32>), %2, shufflemask(1, undef) + %3:_(<2 x f32>) = G_FADD %1, %0 + %4:_(f32) = G_EXTRACT_VECTOR_ELT %3(<2 x f32>), %5(i64) + $s0 = COPY %4(f32) RET_ReallyLR implicit $s0 ... @@ -110,21 +110,21 @@ body: | ; CHECK-LABEL: name: f32_faddp_commuted ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C1]](i64) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s32) = G_FADD [[EVEC]], [[EVEC1]] - ; CHECK-NEXT: $s0 = COPY [[FADD]](s32) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(f32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f32>), [[C1]](i64) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[EVEC]], [[EVEC1]] + ; CHECK-NEXT: $s0 = COPY [[FADD]](f32) ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:_(<2 x s32>) = COPY $d0 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, undef) - %3:_(<2 x s32>) = G_FADD %0, %1 - %4:_(s32) = G_EXTRACT_VECTOR_ELT %3(<2 x s32>), %5(s64) - $s0 = COPY %4(s32) + %0:_(<2 x f32>) = COPY $d0 + %2:_(<2 x f32>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f32>) = G_SHUFFLE_VECTOR %0(<2 x f32>), %2, shufflemask(1, undef) + %3:_(<2 x f32>) = G_FADD %0, %1 + %4:_(f32) = G_EXTRACT_VECTOR_ELT %3(<2 x f32>), %5(i64) + $s0 = COPY %4(f32) RET_ReallyLR implicit $s0 ... @@ -142,21 +142,21 @@ body: | ; CHECK-LABEL: name: wrong_extract_idx ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<2 x s64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x s64>), [[DEF]], shufflemask(1, undef) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(<2 x s64>) = G_FADD [[SHUF]], [[COPY]] - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[FADD]](<2 x s64>), [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[EVEC]](s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f64>) = COPY $q0 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x f64>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<2 x f64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x f64>), [[DEF]], shufflemask(1, undef) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(<2 x f64>) = G_FADD [[SHUF]], [[COPY]] + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[FADD]](<2 x f64>), [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[EVEC]](f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 1 - %1:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(1, undef) - %3:_(<2 x s64>) = G_FADD %1, %0 - %4:_(s64) = G_EXTRACT_VECTOR_ELT %3(<2 x s64>), %5(s64) - $d0 = COPY %4(s64) + %0:_(<2 x f64>) = COPY $q0 + %2:_(<2 x f64>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 1 + %1:_(<2 x f64>) = G_SHUFFLE_VECTOR %0(<2 x f64>), %2, shufflemask(1, undef) + %3:_(<2 x f64>) = G_FADD %1, %0 + %4:_(f64) = G_EXTRACT_VECTOR_ELT %3(<2 x f64>), %5(i64) + $d0 = COPY %4(f64) RET_ReallyLR implicit $d0 ... @@ -174,21 +174,21 @@ body: | ; CHECK-LABEL: name: wrong_shuffle_mask ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<2 x s64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x s64>), [[DEF]], shufflemask(0, undef) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(<2 x s64>) = G_FADD [[SHUF]], [[COPY]] - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[FADD]](<2 x s64>), [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[EVEC]](s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f64>) = COPY $q0 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x f64>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<2 x f64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x f64>), [[DEF]], shufflemask(0, undef) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(<2 x f64>) = G_FADD [[SHUF]], [[COPY]] + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[FADD]](<2 x f64>), [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[EVEC]](f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(0, undef) - %3:_(<2 x s64>) = G_FADD %1, %0 - %4:_(s64) = G_EXTRACT_VECTOR_ELT %3(<2 x s64>), %5(s64) - $d0 = COPY %4(s64) + %0:_(<2 x f64>) = COPY $q0 + %2:_(<2 x f64>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f64>) = G_SHUFFLE_VECTOR %0(<2 x f64>), %2, shufflemask(0, undef) + %3:_(<2 x f64>) = G_FADD %1, %0 + %4:_(f64) = G_EXTRACT_VECTOR_ELT %3(<2 x f64>), %5(i64) + $d0 = COPY %4(f64) RET_ReallyLR implicit $d0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-hoist-same-hands.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-hoist-same-hands.mir index 8e0121f922849..4ab3721440934 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-hoist-same-hands.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-hoist-same-hands.mir @@ -13,18 +13,18 @@ body: | ; CHECK-LABEL: name: or_combine_sext ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR %x, %y - ; CHECK-NEXT: %logic_op:_(s64) = G_SEXT [[OR]](s32) - ; CHECK-NEXT: $x0 = COPY %logic_op(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(i32) = G_OR %x, %y + ; CHECK-NEXT: %logic_op:_(i64) = G_SEXT [[OR]](i32) + ; CHECK-NEXT: $x0 = COPY %logic_op(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %hand1:_(s64) = G_SEXT %x(s32) - %hand2:_(s64) = G_SEXT %y(s32) - %logic_op:_(s64) = G_OR %hand1, %hand2 - $x0 = COPY %logic_op(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %hand1:_(i64) = G_SEXT %x(i32) + %hand2:_(i64) = G_SEXT %y(i32) + %logic_op:_(i64) = G_OR %hand1, %hand2 + $x0 = COPY %logic_op(i64) RET_ReallyLR implicit $x0 ... @@ -40,23 +40,23 @@ body: | ; CHECK-LABEL: name: illegal_ty ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x_wide:_(s32) = COPY $w0 - ; CHECK-NEXT: %y_wide:_(s32) = COPY $w1 - ; CHECK-NEXT: %x:_(s1) = G_TRUNC %x_wide(s32) - ; CHECK-NEXT: %y:_(s1) = G_TRUNC %y_wide(s32) - ; CHECK-NEXT: %hand1:_(s64) = G_SEXT %x(s1) - ; CHECK-NEXT: %hand2:_(s64) = G_SEXT %y(s1) - ; CHECK-NEXT: %logic_op:_(s64) = G_OR %hand1, %hand2 - ; CHECK-NEXT: $x0 = COPY %logic_op(s64) + ; CHECK-NEXT: %x_wide:_(i32) = COPY $w0 + ; CHECK-NEXT: %y_wide:_(i32) = COPY $w1 + ; CHECK-NEXT: %x:_(i1) = G_TRUNC %x_wide(i32) + ; CHECK-NEXT: %y:_(i1) = G_TRUNC %y_wide(i32) + ; CHECK-NEXT: %hand1:_(i64) = G_SEXT %x(i1) + ; CHECK-NEXT: %hand2:_(i64) = G_SEXT %y(i1) + ; CHECK-NEXT: %logic_op:_(i64) = G_OR %hand1, %hand2 + ; CHECK-NEXT: $x0 = COPY %logic_op(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x_wide:_(s32) = COPY $w0 - %y_wide:_(s32) = COPY $w1 - %x:_(s1) = G_TRUNC %x_wide - %y:_(s1) = G_TRUNC %y_wide - %hand1:_(s64) = G_SEXT %x(s1) - %hand2:_(s64) = G_SEXT %y(s1) - %logic_op:_(s64) = G_OR %hand1, %hand2 - $x0 = COPY %logic_op(s64) + %x_wide:_(i32) = COPY $w0 + %y_wide:_(i32) = COPY $w1 + %x:_(i1) = G_TRUNC %x_wide + %y:_(i1) = G_TRUNC %y_wide + %hand1:_(i64) = G_SEXT %x(i1) + %hand2:_(i64) = G_SEXT %y(i1) + %logic_op:_(i64) = G_OR %hand1, %hand2 + $x0 = COPY %logic_op(i64) RET_ReallyLR implicit $x0 ... @@ -71,13 +71,13 @@ body: | ; CHECK-LABEL: name: dont_combine_physreg ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %logic_op:_(s32) = G_OR %x, %y - ; CHECK-NEXT: $w0 = COPY %logic_op(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %logic_op:_(i32) = G_OR %x, %y + ; CHECK-NEXT: $w0 = COPY %logic_op(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %logic_op:_(s32) = G_OR %x, %y - $w0 = COPY %logic_op(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %logic_op:_(i32) = G_OR %x, %y + $w0 = COPY %logic_op(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir index 7cba6b78c5b4e..f9bc49db4a1f5 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir @@ -15,19 +15,19 @@ body: | ; CHECK-LABEL: name: dont_combine_ptr_add ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %reg0:_(s64) = COPY $x0 - ; CHECK-NEXT: %reg1:_(s64) = COPY $x1 + ; CHECK-NEXT: %reg0:_(i64) = COPY $x0 + ; CHECK-NEXT: %reg1:_(i64) = COPY $x1 ; CHECK-NEXT: %ptr:_(p0) = COPY $x2 - ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 6 - ; CHECK-NEXT: %mul:_(s64) = nsw G_MUL %reg0, %cst - ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %ptr, %mul(s64) + ; CHECK-NEXT: %cst:_(i64) = G_CONSTANT i64 6 + ; CHECK-NEXT: %mul:_(i64) = nsw G_MUL %reg0, %cst + ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %ptr, %mul(i64) ; CHECK-NEXT: $x0 = COPY %ptr_add(p0) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:_(s64) = COPY $x0 - %reg1:_(s64) = COPY $x1 + %reg0:_(i64) = COPY $x0 + %reg1:_(i64) = COPY $x1 %ptr:_(p0) = COPY $x2 - %cst:_(s64) = G_CONSTANT i64 6 - %mul:_(s64) = nsw G_MUL %reg0, %cst + %cst:_(i64) = G_CONSTANT i64 6 + %mul:_(i64) = nsw G_MUL %reg0, %cst %ptr_add:_(p0) = G_PTR_ADD %ptr, %mul $x0 = COPY %ptr_add(p0) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-rotate.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-rotate.mir index 2bb4f00bcde72..4229c53649322 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-rotate.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-rotate.mir @@ -17,15 +17,15 @@ body: | ; CHECK-LABEL: name: rotl ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[COPY]], [[C]](s64) - ; CHECK-NEXT: $w0 = COPY [[ROTL]](s32) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(i32) = G_ROTL [[COPY]], [[C]](i64) + ; CHECK-NEXT: $w0 = COPY [[ROTL]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:_(s32) = COPY $w0 - %5:_(s64) = G_CONSTANT i64 -16 - %2:_(s32) = G_ROTL %0, %5(s64) - $w0 = COPY %2(s32) + %0:_(i32) = COPY $w0 + %5:_(i64) = G_CONSTANT i64 -16 + %2:_(i32) = G_ROTL %0, %5(i64) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... @@ -43,15 +43,15 @@ body: | ; CHECK-LABEL: name: rotr ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[COPY]], [[C]](s64) - ; CHECK-NEXT: $w0 = COPY [[ROTR]](s32) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(i32) = G_ROTR [[COPY]], [[C]](i64) + ; CHECK-NEXT: $w0 = COPY [[ROTR]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:_(s32) = COPY $w0 - %5:_(s64) = G_CONSTANT i64 -16 - %2:_(s32) = G_ROTR %0, %5(s64) - $w0 = COPY %2(s32) + %0:_(i32) = COPY $w0 + %5:_(i64) = G_CONSTANT i64 -16 + %2:_(i32) = G_ROTR %0, %5(i64) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... @@ -69,15 +69,15 @@ body: | ; CHECK-LABEL: name: rotl_bitwidth_cst ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[COPY]], [[C]](s64) - ; CHECK-NEXT: $w0 = COPY [[ROTL]](s32) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(i32) = G_ROTL [[COPY]], [[C]](i64) + ; CHECK-NEXT: $w0 = COPY [[ROTL]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:_(s32) = COPY $w0 - %5:_(s64) = G_CONSTANT i64 32 - %2:_(s32) = G_ROTL %0, %5(s64) - $w0 = COPY %2(s32) + %0:_(i32) = COPY $w0 + %5:_(i64) = G_CONSTANT i64 32 + %2:_(i32) = G_ROTL %0, %5(i64) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... @@ -95,15 +95,15 @@ body: | ; CHECK-LABEL: name: rotl_bitwidth_minus_one_cst ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 31 - ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[COPY]], [[C]](s64) - ; CHECK-NEXT: $w0 = COPY [[ROTL]](s32) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 31 + ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(i32) = G_ROTL [[COPY]], [[C]](i64) + ; CHECK-NEXT: $w0 = COPY [[ROTL]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:_(s32) = COPY $w0 - %5:_(s64) = G_CONSTANT i64 31 - %2:_(s32) = G_ROTL %0, %5(s64) - $w0 = COPY %2(s32) + %0:_(i32) = COPY $w0 + %5:_(i64) = G_CONSTANT i64 31 + %2:_(i32) = G_ROTL %0, %5(i64) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir index ac0d561c99a1b..c2c457884c786 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir @@ -10,12 +10,12 @@ body: | ; CHECK-LABEL: name: test_combine_select_same_res ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) - %0:_(s64) = COPY $x0 - %1:_(s1) = G_TRUNC %0 - %2:_(s64) = G_SELECT %1, %0, %0 - $x0 = COPY %2(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) + %0:_(i64) = COPY $x0 + %1:_(i1) = G_TRUNC %0 + %2:_(i64) = G_SELECT %1, %0, %0 + $x0 = COPY %2(i64) ... --- # select (undef, x, y) -> y @@ -27,13 +27,13 @@ body: | ; CHECK-LABEL: name: test_combine_select_undef_res0_res1 ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s1) = G_IMPLICIT_DEF - %3:_(s64) = G_SELECT %2, %0, %1 - $x0 = COPY %3(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x1 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) + %0:_(i64) = COPY $x0 + %1:_(i64) = COPY $x1 + %2:_(i1) = G_IMPLICIT_DEF + %3:_(i64) = G_SELECT %2, %0, %1 + $x0 = COPY %3(i64) ... --- # select (false, x, y) -> y @@ -45,13 +45,13 @@ body: | ; CHECK-LABEL: name: test_combine_select_false_res0_res1 ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s1) = G_CONSTANT i1 false - %3:_(s64) = G_SELECT %2, %0, %1 - $x0 = COPY %3(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x1 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) + %0:_(i64) = COPY $x0 + %1:_(i64) = COPY $x1 + %2:_(i1) = G_CONSTANT i1 false + %3:_(i64) = G_SELECT %2, %0, %1 + $x0 = COPY %3(i64) ... --- # select (true, x, y) -> x @@ -63,11 +63,11 @@ body: | ; CHECK-LABEL: name: test_combine_select_true_res0_res1 ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s1) = G_CONSTANT i1 true - %3:_(s64) = G_SELECT %2, %0, %1 - $x0 = COPY %3(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) + %0:_(i64) = COPY $x0 + %1:_(i64) = COPY $x1 + %2:_(i1) = G_CONSTANT i1 true + %3:_(i64) = G_SELECT %2, %0, %1 + $x0 = COPY %3(i64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-arith-extended-reg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-arith-extended-reg.mir index 9389fff12fb93..49ed1f35b03af 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-arith-extended-reg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-arith-extended-reg.mir @@ -203,8 +203,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_SEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_SEXT %1(i8) %add_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_ADD %add_lhs, %ext $w3 = COPY %res(i32) @@ -229,8 +229,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_ZEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_ZEXT %1(i8) %add_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_ADD %add_lhs, %ext $w3 = COPY %res(i32) @@ -255,8 +255,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_ANYEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_ANYEXT %1(i8) %add_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_ADD %add_lhs, %ext $w3 = COPY %res(i32) @@ -541,8 +541,8 @@ body: | bb.0: liveins: $w1, $w2, $x2 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_SEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_SEXT %1(i8) %sub_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_SUB %sub_lhs, %ext $w3 = COPY %res(i32) @@ -567,8 +567,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_ZEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_ZEXT %1(i8) %sub_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_SUB %sub_lhs, %ext $w3 = COPY %res(i32) @@ -593,8 +593,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_ANYEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_ANYEXT %1(i8) %sub_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_SUB %sub_lhs, %ext $w3 = COPY %res(i32) @@ -721,8 +721,8 @@ body: | %0:gpr(p0) = COPY $x0 %1:gpr(i32) = COPY $w1 %2:gpr(p0) = COPY $x2 - %small:gpr(s8) = G_TRUNC %1 - %zext:gpr(i64) = G_ZEXT %small(s8) + %small:gpr(i8) = G_TRUNC %1 + %zext:gpr(i64) = G_ZEXT %small(i8) %cst:gpr(i64) = G_CONSTANT i64 3 %shl:gpr(i64) = G_SHL %zext, %cst(i64) %gep:gpr(p0) = G_PTR_ADD %0, %shl(i64) @@ -793,8 +793,8 @@ body: | %0:gpr(p0) = COPY $x0 %1:gpr(i32) = COPY $w1 %2:gpr(p0) = COPY $x2 - %small:gpr(s8) = G_TRUNC %1 - %zext:gpr(i64) = G_SEXT %small(s8) + %small:gpr(i8) = G_TRUNC %1 + %zext:gpr(i64) = G_SEXT %small(i8) %cst:gpr(i64) = G_CONSTANT i64 3 %shl:gpr(i64) = G_SHL %zext, %cst(i64) %gep:gpr(p0) = G_PTR_ADD %0, %shl(i64) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-atomic-load-store.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-atomic-load-store.mir index da3c962f2468e..5d9b7e0d42a01 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-atomic-load-store.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-atomic-load-store.mir @@ -32,12 +32,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load acquire (s8) from %ir.ptr, align 8) + ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load acquire (i8) from %ir.ptr, align 8) ; CHECK-NEXT: $w0 = COPY [[LDARB]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(s32) = G_LOAD %0(p0) :: (load acquire (s8) from %ir.ptr, align 8) - $w0 = COPY %2(s32) + %2:gpr(i32) = G_LOAD %0(p0) :: (load acquire (i8) from %ir.ptr, align 8) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... @@ -50,13 +50,13 @@ body: | bb.1: ; CHECK-LABEL: name: anyext_load_monotonic_i32 ; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY $xzr - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load monotonic (s32) from `ptr null`) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load monotonic (i32) from `ptr null`) ; CHECK-NEXT: %ld:gpr64all = SUBREG_TO_REG [[LDRWui]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY %ld ; CHECK-NEXT: RET_ReallyLR implicit $x0 %1:gpr(p0) = G_CONSTANT i64 0 - %ld:gpr(s64) = G_LOAD %1(p0) :: (load monotonic (s32) from `ptr null`) - $x0 = COPY %ld(s64) + %ld:gpr(i64) = G_LOAD %1(p0) :: (load monotonic (i32) from `ptr null`) + $x0 = COPY %ld(i64) RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-atomicrmw.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-atomicrmw.mir index 457c5d6411b64..7d8c1e0f1b28e 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-atomicrmw.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-atomicrmw.mir @@ -33,12 +33,12 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 - ; CHECK-NEXT: [[SWPX:%[0-9]+]]:gpr64 = SWPX [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (s64) on %ir.addr) + ; CHECK-NEXT: [[SWPX:%[0-9]+]]:gpr64 = SWPX [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (i64) on %ir.addr) ; CHECK-NEXT: $x0 = COPY [[SWPX]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 1 - %2:gpr(s64) = G_ATOMICRMW_XCHG %0, %1 :: (load store monotonic (s64) on %ir.addr) - $x0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 1 + %2:gpr(i64) = G_ATOMICRMW_XCHG %0, %1 :: (load store monotonic (i64) on %ir.addr) + $x0 = COPY %2(i64) ... --- name: atomicrmw_add_i64 @@ -55,12 +55,12 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 - ; CHECK-NEXT: [[LDADDX:%[0-9]+]]:gpr64 = LDADDX [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (s64) on %ir.addr) + ; CHECK-NEXT: [[LDADDX:%[0-9]+]]:gpr64 = LDADDX [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (i64) on %ir.addr) ; CHECK-NEXT: $x0 = COPY [[LDADDX]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 1 - %2:gpr(s64) = G_ATOMICRMW_ADD %0, %1 :: (load store monotonic (s64) on %ir.addr) - $x0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 1 + %2:gpr(i64) = G_ATOMICRMW_ADD %0, %1 :: (load store monotonic (i64) on %ir.addr) + $x0 = COPY %2(i64) ... --- name: atomicrmw_add_i32 @@ -76,12 +76,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDADDALW:%[0-9]+]]:gpr32 = LDADDALW [[MOVi32imm]], [[COPY]] :: (load store seq_cst (s32) on %ir.addr) + ; CHECK-NEXT: [[LDADDALW:%[0-9]+]]:gpr32 = LDADDALW [[MOVi32imm]], [[COPY]] :: (load store seq_cst (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDADDALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_ADD %0, %1 :: (load store seq_cst (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_ADD %0, %1 :: (load store seq_cst (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -98,12 +98,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDADDALW:%[0-9]+]]:gpr32 = LDADDALW [[MOVi32imm]], [[COPY]] :: (load store seq_cst (s32) on %ir.addr) + ; CHECK-NEXT: [[LDADDALW:%[0-9]+]]:gpr32 = LDADDALW [[MOVi32imm]], [[COPY]] :: (load store seq_cst (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDADDALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_ADD %0, %1 :: (load store seq_cst (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_ADD %0, %1 :: (load store seq_cst (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -121,12 +121,12 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK-NEXT: [[ORNWrr:%[0-9]+]]:gpr32 = ORNWrr $wzr, [[MOVi32imm]] - ; CHECK-NEXT: [[LDCLRAW:%[0-9]+]]:gpr32 = LDCLRAW [[ORNWrr]], [[COPY]] :: (load store acquire (s32) on %ir.addr) + ; CHECK-NEXT: [[LDCLRAW:%[0-9]+]]:gpr32 = LDCLRAW [[ORNWrr]], [[COPY]] :: (load store acquire (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDCLRAW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_AND %0, %1 :: (load store acquire (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_AND %0, %1 :: (load store acquire (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -143,12 +143,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDSETLW:%[0-9]+]]:gpr32 = LDSETLW [[MOVi32imm]], [[COPY]] :: (load store release (s32) on %ir.addr) + ; CHECK-NEXT: [[LDSETLW:%[0-9]+]]:gpr32 = LDSETLW [[MOVi32imm]], [[COPY]] :: (load store release (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDSETLW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_OR %0, %1 :: (load store release (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_OR %0, %1 :: (load store release (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -165,12 +165,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDEORALW:%[0-9]+]]:gpr32 = LDEORALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDEORALW:%[0-9]+]]:gpr32 = LDEORALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDEORALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_XOR %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_XOR %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -187,12 +187,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDSMINALW:%[0-9]+]]:gpr32 = LDSMINALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDSMINALW:%[0-9]+]]:gpr32 = LDSMINALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDSMINALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_MIN %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_MIN %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -209,12 +209,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDSMAXALW:%[0-9]+]]:gpr32 = LDSMAXALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDSMAXALW:%[0-9]+]]:gpr32 = LDSMAXALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDSMAXALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_MAX %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_MAX %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -231,12 +231,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDUMINALW:%[0-9]+]]:gpr32 = LDUMINALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDUMINALW:%[0-9]+]]:gpr32 = LDUMINALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDUMINALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_UMIN %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_UMIN %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -253,10 +253,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDUMAXALW:%[0-9]+]]:gpr32 = LDUMAXALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDUMAXALW:%[0-9]+]]:gpr32 = LDUMAXALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDUMAXALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_UMAX %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_UMAX %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bit.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bit.mir index e3edb62809774..e64da1ec822ce 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-bit.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bit.mir @@ -20,11 +20,11 @@ body: | ; CHECK-NEXT: %bit:fpr64 = BSPv8i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $d0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %lhs:fpr(<2 x s32>) = COPY $d0 - %mhs:fpr(<2 x s32>) = COPY $d1 - %rhs:fpr(<2 x s32>) = COPY $d2 - %bit:fpr(<2 x s32>) = G_BSP %lhs, %mhs, %rhs - $d0 = COPY %bit(<2 x s32>) + %lhs:fpr(<2 x i32>) = COPY $d0 + %mhs:fpr(<2 x i32>) = COPY $d1 + %rhs:fpr(<2 x i32>) = COPY $d2 + %bit:fpr(<2 x i32>) = G_BSP %lhs, %mhs, %rhs + $d0 = COPY %bit(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -45,11 +45,11 @@ body: | ; CHECK-NEXT: %bit:fpr64 = BSPv8i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $d0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %lhs:fpr(<4 x s16>) = COPY $d0 - %mhs:fpr(<4 x s16>) = COPY $d1 - %rhs:fpr(<4 x s16>) = COPY $d2 - %bit:fpr(<4 x s16>) = G_BSP %lhs, %mhs, %rhs - $d0 = COPY %bit(<4 x s16>) + %lhs:fpr(<4 x i16>) = COPY $d0 + %mhs:fpr(<4 x i16>) = COPY $d1 + %rhs:fpr(<4 x i16>) = COPY $d2 + %bit:fpr(<4 x i16>) = G_BSP %lhs, %mhs, %rhs + $d0 = COPY %bit(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -71,11 +71,11 @@ body: | ; CHECK-NEXT: %bit:fpr128 = BSPv16i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $q0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lhs:fpr(<2 x s64>) = COPY $q0 - %mhs:fpr(<2 x s64>) = COPY $q1 - %rhs:fpr(<2 x s64>) = COPY $q2 - %bit:fpr(<2 x s64>) = G_BSP %lhs, %mhs, %rhs - $q0 = COPY %bit(<2 x s64>) + %lhs:fpr(<2 x i64>) = COPY $q0 + %mhs:fpr(<2 x i64>) = COPY $q1 + %rhs:fpr(<2 x i64>) = COPY $q2 + %bit:fpr(<2 x i64>) = G_BSP %lhs, %mhs, %rhs + $q0 = COPY %bit(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -97,11 +97,11 @@ body: | ; CHECK-NEXT: %bit:fpr128 = BSPv16i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $q0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lhs:fpr(<4 x s32>) = COPY $q0 - %mhs:fpr(<4 x s32>) = COPY $q1 - %rhs:fpr(<4 x s32>) = COPY $q2 - %bit:fpr(<4 x s32>) = G_BSP %lhs, %mhs, %rhs - $q0 = COPY %bit(<4 x s32>) + %lhs:fpr(<4 x i32>) = COPY $q0 + %mhs:fpr(<4 x i32>) = COPY $q1 + %rhs:fpr(<4 x i32>) = COPY $q2 + %bit:fpr(<4 x i32>) = G_BSP %lhs, %mhs, %rhs + $q0 = COPY %bit(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -123,11 +123,11 @@ body: | ; CHECK-NEXT: %bit:fpr128 = BSPv16i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $q0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lhs:fpr(<8 x s16>) = COPY $q0 - %mhs:fpr(<8 x s16>) = COPY $q1 - %rhs:fpr(<8 x s16>) = COPY $q2 - %bit:fpr(<8 x s16>) = G_BSP %lhs, %mhs, %rhs - $q0 = COPY %bit(<8 x s16>) + %lhs:fpr(<8 x i16>) = COPY $q0 + %mhs:fpr(<8 x i16>) = COPY $q1 + %rhs:fpr(<8 x i16>) = COPY $q2 + %bit:fpr(<8 x i16>) = G_BSP %lhs, %mhs, %rhs + $q0 = COPY %bit(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -149,9 +149,9 @@ body: | ; CHECK-NEXT: %bit:fpr128 = BSPv16i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $q0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lhs:fpr(<16 x s8>) = COPY $q0 - %mhs:fpr(<16 x s8>) = COPY $q1 - %rhs:fpr(<16 x s8>) = COPY $q2 - %bit:fpr(<16 x s8>) = G_BSP %lhs, %mhs, %rhs - $q0 = COPY %bit(<16 x s8>) + %lhs:fpr(<16 x i8>) = COPY $q0 + %mhs:fpr(<16 x i8>) = COPY $q1 + %rhs:fpr(<16 x i8>) = COPY $q2 + %bit:fpr(<16 x i8>) = G_BSP %lhs, %mhs, %rhs + $q0 = COPY %bit(<16 x i8>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast-bigendian.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast-bigendian.mir index 74436c21d79d8..fb38abd071c0f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast-bigendian.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast-bigendian.mir @@ -17,7 +17,7 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[COPY1]] ; CHECK-NEXT: [[REV64v2i32_:%[0-9]+]]:fpr64 = REV64v2i32 [[COPY2]] ; CHECK-NEXT: $x0 = COPY [[REV64v2i32_]] - %0:fpr(<2 x s32>) = COPY $x0 - %1:fpr(s64) = G_BITCAST %0 - $x0 = COPY %1(s64) + %0:fpr(<2 x i32>) = COPY $x0 + %1:fpr(i64) = G_BITCAST %0 + $x0 = COPY %1(i64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast.mir index e615b4d8efbb4..8ffea5447afde 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast.mir @@ -35,9 +35,9 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]] ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY [[COPY1]] ; CHECK-NEXT: $w0 = COPY [[COPY2]] - %0(s32) = COPY $w0 - %1(<2 x s16>) = G_BITCAST %0 - %2(s32) = G_BITCAST %1 + %0(i32) = COPY $w0 + %1(<2 x i16>) = G_BITCAST %0 + %2(i32) = G_BITCAST %1 $w0 = COPY %2 ... @@ -61,9 +61,9 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[COPY]] ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr32 = COPY [[COPY1]] ; CHECK-NEXT: $s0 = COPY [[COPY2]] - %0(s32) = COPY $s0 - %1(<2 x s16>) = G_BITCAST %0 - %2(s32) = G_BITCAST %1 + %0(i32) = COPY $s0 + %1(<2 x i16>) = G_BITCAST %0 + %2(i32) = G_BITCAST %1 $s0 = COPY %2 ... @@ -86,8 +86,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY $w0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]] ; CHECK-NEXT: $s0 = COPY [[COPY1]] - %0(s32) = COPY $w0 - %1(<2 x s16>) = G_BITCAST %0 + %0(i32) = COPY $w0 + %1(<2 x i16>) = G_BITCAST %0 $s0 = COPY %1 ... @@ -110,9 +110,9 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr32 = COPY $s0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[COPY]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] - %0(<2 x s16>) = COPY $s0 - %1(s32) = G_BITCAST %0 - $w0 = COPY %1(s32) + %0(<2 x i16>) = COPY $s0 + %1(i32) = G_BITCAST %0 + $w0 = COPY %1(i32) ... --- @@ -136,10 +136,10 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[COPY]] ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]] ; CHECK-NEXT: $x0 = COPY [[COPY2]] - %0(s64) = COPY $x0 - %1(<2 x s32>) = G_BITCAST %0 - %2(s64) = G_BITCAST %1 - $x0 = COPY %2(s64) + %0(i64) = COPY $x0 + %1(<2 x i32>) = G_BITCAST %0 + %2(i64) = G_BITCAST %1 + $x0 = COPY %2(i64) ... --- @@ -160,8 +160,8 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: $d0 = COPY [[COPY]] - %0(s64) = COPY $d0 - %1(<2 x s32>) = G_BITCAST %0 + %0(i64) = COPY $d0 + %1(<2 x i32>) = G_BITCAST %0 $d0 = COPY %1 ... @@ -183,8 +183,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[COPY]] ; CHECK-NEXT: $d0 = COPY [[COPY1]] - %0(s64) = COPY $x0 - %1(<2 x s32>) = G_BITCAST %0 + %0(i64) = COPY $x0 + %1(<2 x i32>) = G_BITCAST %0 $d0 = COPY %1 ... @@ -207,8 +207,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64all = COPY [[COPY]] ; CHECK-NEXT: $x0 = COPY [[COPY1]] - %0(s64) = COPY $d0 - %1(<2 x s32>) = G_BITCAST %0 + %0(i64) = COPY $d0 + %1(<2 x i32>) = G_BITCAST %0 $x0 = COPY %1 ... @@ -230,9 +230,9 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: $x0 = COPY [[COPY]] - %0(s64) = COPY $d0 - %1(<2 x s32>) = G_BITCAST %0 - $x0 = COPY %1(<2 x s32>) + %0(i64) = COPY $d0 + %1(<2 x i32>) = G_BITCAST %0 + $x0 = COPY %1(<2 x i32>) ... --- @@ -253,7 +253,7 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: $x0 = COPY [[COPY]] - %0(s64) = COPY $d0 - %1(<8 x s8>) = G_BITCAST %0 - $x0 = COPY %1(<8 x s8>) + %0(i64) = COPY $d0 + %1(<8 x i8>) = G_BITCAST %0 + $x0 = COPY %1(<8 x i8>) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-br.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-br.mir index e47411b7b178a..fae3870534ad9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-br.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-br.mir @@ -42,7 +42,7 @@ registers: body: | bb.0: successors: %bb.0, %bb.1 - %1(s32) = COPY $w0 + %1(i32) = COPY $w0 G_BRCOND %1, %bb.1 G_BR %bb.0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir index d0f2c9ceed7ef..5df0ea7811e83 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir @@ -13,7 +13,7 @@ body: | ; CHECK-NEXT: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: TBZW [[LDRBBui]], 0, %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: @@ -26,7 +26,7 @@ body: | liveins: $x0 %0:gpr(p0) = COPY $x0 - %8:gpr(i8) = G_LOAD %0(p0) :: (load (s8)) + %8:gpr(i8) = G_LOAD %0(p0) :: (load (i8)) %4:gpr(i32) = G_ANYEXT %8(i8) %5:gpr(i32) = G_CONSTANT i32 1 %6:gpr(i32) = G_XOR %4, %5 @@ -52,7 +52,7 @@ body: | ; CHECK-NEXT: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: TBZW [[LDRBBui]], 0, %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: @@ -67,7 +67,7 @@ body: | liveins: $x0 %0:gpr(p0) = COPY $x0 - %8:gpr(i8) = G_LOAD %0(p0) :: (load (s8)) + %8:gpr(i8) = G_LOAD %0(p0) :: (load (i8)) %4:gpr(i64) = G_ANYEXT %8(i8) %5:gpr(i64) = G_CONSTANT i64 1 %6:gpr(i64) = G_XOR %4, %5 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir index 5e0121682e327..46773eab46eaf 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir @@ -21,8 +21,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 ; CHECK-NEXT: [[REVWr:%[0-9]+]]:gpr32 = REVWr [[COPY]] ; CHECK-NEXT: $w0 = COPY [[REVWr]] - %0(s32) = COPY $w0 - %1(s32) = G_BSWAP %0 + %0(i32) = COPY $w0 + %1(i32) = G_BSWAP %0 $w0 = COPY %1 ... @@ -45,8 +45,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 ; CHECK-NEXT: [[REVXr:%[0-9]+]]:gpr64 = REVXr [[COPY]] ; CHECK-NEXT: $x0 = COPY [[REVXr]] - %0(s64) = COPY $x0 - %1(s64) = G_BSWAP %0 + %0(i64) = COPY $x0 + %1(i64) = G_BSWAP %0 $x0 = COPY %1 ... @@ -68,9 +68,9 @@ body: | ; CHECK-NEXT: [[REV16v8i8_:%[0-9]+]]:fpr64 = REV16v8i8 [[COPY]] ; CHECK-NEXT: $d0 = COPY [[REV16v8i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<4 x s16>) = G_BSWAP %0 - $d0 = COPY %1(<4 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<4 x i16>) = G_BSWAP %0 + $d0 = COPY %1(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -91,9 +91,9 @@ body: | ; CHECK-NEXT: [[REV16v16i8_:%[0-9]+]]:fpr128 = REV16v16i8 [[COPY]] ; CHECK-NEXT: $q0 = COPY [[REV16v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:fpr(<8 x s16>) = G_BSWAP %0 - $q0 = COPY %1(<8 x s16>) + %0:fpr(<8 x i16>) = COPY $q0 + %1:fpr(<8 x i16>) = G_BSWAP %0 + $q0 = COPY %1(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -115,9 +115,9 @@ body: | ; CHECK-NEXT: [[REV32v16i8_:%[0-9]+]]:fpr128 = REV32v16i8 [[COPY]] ; CHECK-NEXT: $q0 = COPY [[REV32v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = G_BSWAP %0 - $q0 = COPY %1(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = G_BSWAP %0 + $q0 = COPY %1(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -139,9 +139,9 @@ body: | ; CHECK-NEXT: [[REV32v8i8_:%[0-9]+]]:fpr64 = REV32v8i8 [[COPY]] ; CHECK-NEXT: $d0 = COPY [[REV32v8i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = G_BSWAP %0 - $d0 = COPY %1(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = G_BSWAP %0 + $d0 = COPY %1(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -163,9 +163,9 @@ body: | ; CHECK-NEXT: [[REV64v16i8_:%[0-9]+]]:fpr128 = REV64v16i8 [[COPY]] ; CHECK-NEXT: $q0 = COPY [[REV64v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = G_BSWAP %0 - $q0 = COPY %1(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = G_BSWAP %0 + $q0 = COPY %1(<2 x i64>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-build-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-build-vector.mir index 0b2121db4e7c4..4e88d5edd6df2 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-build-vector.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-build-vector.mir @@ -33,12 +33,12 @@ body: | ; CHECK-NEXT: [[INSvi32lane2:%[0-9]+]]:fpr128 = INSvi32lane [[INSvi32lane1]], 3, [[INSERT_SUBREG3]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi32lane2]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(s32) = COPY $s0 - %1:fpr(s32) = COPY $s1 - %2:fpr(s32) = COPY $s2 - %3:fpr(s32) = COPY $s3 - %4:fpr(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32) - $q0 = COPY %4(<4 x s32>) + %0:fpr(i32) = COPY $s0 + %1:fpr(i32) = COPY $s1 + %2:fpr(i32) = COPY $s2 + %3:fpr(i32) = COPY $s3 + %4:fpr(<4 x i32>) = G_BUILD_VECTOR %0(i32), %1(i32), %2(i32), %3(i32) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -67,10 +67,10 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG]], 1, [[INSERT_SUBREG1]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(s64) = COPY $d0 - %1:fpr(s64) = COPY $d1 - %4:fpr(<2 x s64>) = G_BUILD_VECTOR %0(s64), %1(s64) - $q0 = COPY %4(<2 x s64>) + %0:fpr(i64) = COPY $d0 + %1:fpr(i64) = COPY $d1 + %4:fpr(<2 x i64>) = G_BUILD_VECTOR %0(i64), %1(i64) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -101,12 +101,12 @@ body: | ; CHECK-NEXT: [[INSvi32gpr2:%[0-9]+]]:fpr128 = INSvi32gpr [[INSvi32gpr1]], 3, [[COPY3]] ; CHECK-NEXT: $q0 = COPY [[INSvi32gpr2]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = COPY $w2 - %3:gpr(s32) = COPY $w3 - %4:fpr(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32) - $q0 = COPY %4(<4 x s32>) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = COPY $w2 + %3:gpr(i32) = COPY $w3 + %4:fpr(<4 x i32>) = G_BUILD_VECTOR %0(i32), %1(i32), %2(i32), %3(i32) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -133,10 +133,10 @@ body: | ; CHECK-NEXT: [[INSvi64gpr:%[0-9]+]]:fpr128 = INSvi64gpr [[INSERT_SUBREG]], 1, [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[INSvi64gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %4:fpr(<2 x s64>) = G_BUILD_VECTOR %0(s64), %1(s64) - $q0 = COPY %4(<2 x s64>) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %4:fpr(<2 x i64>) = G_BUILD_VECTOR %0(i64), %1(i64) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -191,13 +191,13 @@ body: | ; CHECK-NEXT: $q0 = COPY [[MOVIv2d_ns]] ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %2:gpr(s32) = G_CONSTANT i32 0 - %3:fpr(s32) = COPY %2(s32) - %4:fpr(s32) = COPY %2(s32) - %5:fpr(s32) = COPY %2(s32) - %6:fpr(s32) = COPY %2(s32) - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %3(s32), %4(s32), %5(s32), %6(s32) - $q0 = COPY %1(<4 x s32>) + %2:gpr(i32) = G_CONSTANT i32 0 + %3:fpr(i32) = COPY %2(i32) + %4:fpr(i32) = COPY %2(i32) + %5:fpr(i32) = COPY %2(i32) + %6:fpr(i32) = COPY %2(i32) + %1:fpr(<4 x i32>) = G_BUILD_VECTOR %3(i32), %4(i32), %5(i32), %6(i32) + $q0 = COPY %1(<4 x i32>) RET_ReallyLR ... --- @@ -222,17 +222,17 @@ body: | ; CHECK-NEXT: $d0 = COPY [[COPY]] ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %2:gpr(s8) = G_CONSTANT i8 0 - %3:fpr(s8) = COPY %2(s8) - %4:fpr(s8) = COPY %2(s8) - %5:fpr(s8) = COPY %2(s8) - %6:fpr(s8) = COPY %2(s8) - %7:fpr(s8) = COPY %2(s8) - %8:fpr(s8) = COPY %2(s8) - %9:fpr(s8) = COPY %2(s8) - %10:fpr(s8) = COPY %2(s8) - %1:fpr(<8 x s8>) = G_BUILD_VECTOR %3(s8), %4(s8), %5(s8), %6(s8), %7(s8), %8(s8), %9(s8), %10(s8) - $d0 = COPY %1(<8 x s8>) + %2:gpr(i8) = G_CONSTANT i8 0 + %3:fpr(i8) = COPY %2(i8) + %4:fpr(i8) = COPY %2(i8) + %5:fpr(i8) = COPY %2(i8) + %6:fpr(i8) = COPY %2(i8) + %7:fpr(i8) = COPY %2(i8) + %8:fpr(i8) = COPY %2(i8) + %9:fpr(i8) = COPY %2(i8) + %10:fpr(i8) = COPY %2(i8) + %1:fpr(<8 x i8>) = G_BUILD_VECTOR %3(i8), %4(i8), %5(i8), %6(i8), %7(i8), %8(i8), %9(i8), %10(i8) + $d0 = COPY %1(<8 x i8>) RET_ReallyLR ... --- @@ -253,10 +253,10 @@ body: | ; CHECK-NEXT: %bv:fpr128 = SUBREG_TO_REG %val, %subreg.ssub ; CHECK-NEXT: $q0 = COPY %bv ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %val:fpr(s32) = COPY $s0 - %undef:fpr(s32) = G_IMPLICIT_DEF - %bv:fpr(<4 x s32>) = G_BUILD_VECTOR %val(s32), %undef(s32), %undef(s32), %undef(s32) - $q0 = COPY %bv(<4 x s32>) + %val:fpr(i32) = COPY $s0 + %undef:fpr(i32) = G_IMPLICIT_DEF + %bv:fpr(<4 x i32>) = G_BUILD_VECTOR %val(i32), %undef(i32), %undef(i32), %undef(i32) + $q0 = COPY %bv(<4 x i32>) RET_ReallyLR implicit $q0 ... ... @@ -279,9 +279,9 @@ body: | ; CHECK-NEXT: %bv:fpr128 = INSERT_SUBREG [[DEF]], %val, %subreg.ssub ; CHECK-NEXT: $q0 = COPY %bv ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %val:gpr(s32) = COPY $w0 - %undef:gpr(s32) = G_IMPLICIT_DEF - %bv:fpr(<4 x s32>) = G_BUILD_VECTOR %val(s32), %undef(s32), %undef(s32), %undef(s32) - $q0 = COPY %bv(<4 x s32>) + %val:gpr(i32) = COPY $w0 + %undef:gpr(i32) = G_IMPLICIT_DEF + %bv:fpr(<4 x i32>) = G_BUILD_VECTOR %val(i32), %undef(i32), %undef(i32), %undef(i32) + $q0 = COPY %bv(<4 x i32>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir index 0da29c9d0c110..7fd1c8b419ab9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir @@ -21,9 +21,9 @@ body: | liveins: $w0 successors: %bb.0, %bb.1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s32) = G_ICMP intpred(eq), %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = G_CONSTANT i32 0 + %2:gpr(i32) = G_ICMP intpred(eq), %0, %1 G_BRCOND %2, %bb.1 G_BR %bb.0 @@ -50,9 +50,9 @@ body: | liveins: $x0 successors: %bb.0, %bb.1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 0 - %2:gpr(s32) = G_ICMP intpred(eq), %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = G_CONSTANT i64 0 + %2:gpr(i32) = G_ICMP intpred(eq), %0, %1 G_BRCOND %2, %bb.1 G_BR %bb.0 @@ -79,9 +79,9 @@ body: | liveins: $w0 successors: %bb.0, %bb.1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s32) = G_ICMP intpred(ne), %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = G_CONSTANT i32 0 + %2:gpr(i32) = G_ICMP intpred(ne), %0, %1 G_BRCOND %2, %bb.1 G_BR %bb.0 @@ -108,9 +108,9 @@ body: | liveins: $x0 successors: %bb.0, %bb.1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 0 - %2:gpr(s32) = G_ICMP intpred(ne), %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = G_CONSTANT i64 0 + %2:gpr(i32) = G_ICMP intpred(ne), %0, %1 G_BRCOND %2, %bb.1 G_BR %bb.0 @@ -134,7 +134,7 @@ body: | ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x80000000) ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (s64)) + ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (i64)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -143,14 +143,14 @@ body: | liveins: $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(s64) = G_CONSTANT i64 0 - %1:gpr(p0) = G_INTTOPTR %2(s64) - %4:gpr(s32) = G_ICMP intpred(eq), %0(p0), %1 + %2:gpr(i64) = G_CONSTANT i64 0 + %1:gpr(p0) = G_INTTOPTR %2(i64) + %4:gpr(i32) = G_ICMP intpred(eq), %0(p0), %1 G_BRCOND %4, %bb.3 bb.2: - %5:gpr(s64) = G_CONSTANT i64 0 - G_STORE %5(s64), %0(p0) :: (store (s64)) + %5:gpr(i64) = G_CONSTANT i64 0 + G_STORE %5(i64), %0(p0) :: (store (i64)) bb.3: RET_ReallyLR @@ -169,14 +169,14 @@ body: | ; CHECK-NEXT: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui [[COPY]], 0 :: (load (s64)) + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui [[COPY]], 0 :: (load (i64)) ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[LDRXui]], 42, 0, implicit-def $nzcv ; CHECK-NEXT: Bcc 0, %bb.2, implicit $nzcv ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x80000000) ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (s64)) + ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (i64)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -185,15 +185,15 @@ body: | liveins: $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(s64) = G_CONSTANT i64 42 - %4:gpr(s64) = G_CONSTANT i64 0 - %1:gpr(s64) = G_LOAD %0(p0) :: (load (s64)) - %5:gpr(s32) = G_ICMP intpred(eq), %1(s64), %2 + %2:gpr(i64) = G_CONSTANT i64 42 + %4:gpr(i64) = G_CONSTANT i64 0 + %1:gpr(i64) = G_LOAD %0(p0) :: (load (i64)) + %5:gpr(i32) = G_ICMP intpred(eq), %1(i64), %2 G_BRCOND %5, %bb.3 bb.2: - %6:gpr(s64) = G_CONSTANT i64 0 - G_STORE %6(s64), %0(p0) :: (store (s64)) + %6:gpr(i64) = G_CONSTANT i64 0 + G_STORE %6(i64), %0(p0) :: (store (i64)) bb.3: RET_ReallyLR diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-cmpxchg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-cmpxchg.mir index 33cb75f7b8f46..c8e343ac67972 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-cmpxchg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-cmpxchg.mir @@ -23,13 +23,13 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $wzr ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[CASW:%[0-9]+]]:gpr32 = CASW [[COPY1]], [[MOVi32imm]], [[COPY]] :: (load store monotonic (s32) on %ir.addr) + ; CHECK-NEXT: [[CASW:%[0-9]+]]:gpr32 = CASW [[COPY1]], [[MOVi32imm]], [[COPY]] :: (load store monotonic (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[CASW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (s32) on %ir.addr) - $w0 = COPY %3(s32) + %1:gpr(i32) = G_CONSTANT i32 0 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (i32) on %ir.addr) + $w0 = COPY %3(i32) ... --- @@ -48,11 +48,11 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $xzr ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 - ; CHECK-NEXT: [[CASX:%[0-9]+]]:gpr64 = CASX [[COPY1]], [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (s64) on %ir.addr) + ; CHECK-NEXT: [[CASX:%[0-9]+]]:gpr64 = CASX [[COPY1]], [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (i64) on %ir.addr) ; CHECK-NEXT: $x0 = COPY [[CASX]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 0 - %2:gpr(s64) = G_CONSTANT i64 1 - %3:gpr(s64) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (s64) on %ir.addr) - $x0 = COPY %3(s64) + %1:gpr(i64) = G_CONSTANT i64 0 + %2:gpr(i64) = G_CONSTANT i64 1 + %3:gpr(i64) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (i64) on %ir.addr) + $x0 = COPY %3(i64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-concat-vectors.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-concat-vectors.mir index 53d8b82509481..23dc446156173 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-concat-vectors.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-concat-vectors.mir @@ -28,10 +28,10 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<4 x s32>) = G_CONCAT_VECTORS %0(<2 x s32>), %1(<2 x s32>) - $q0 = COPY %2(<4 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<4 x i32>) = G_CONCAT_VECTORS %0(<2 x i32>), %1(<2 x i32>) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -62,10 +62,10 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<4 x s16>) = COPY $d1 - %2:fpr(<8 x s16>) = G_CONCAT_VECTORS %0(<4 x s16>), %1(<4 x s16>) - $q0 = COPY %2(<8 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<4 x i16>) = COPY $d1 + %2:fpr(<8 x i16>) = G_CONCAT_VECTORS %0(<4 x i16>), %1(<4 x i16>) + $q0 = COPY %2(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -86,10 +86,10 @@ body: | ; CHECK-NEXT: %concat:fpr128 = INSERT_SUBREG [[DEF]], %a, %subreg.dsub ; CHECK-NEXT: $q0 = COPY %concat ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %a:fpr(<8 x s8>) = G_IMPLICIT_DEF - %b:fpr(<8 x s8>) = G_IMPLICIT_DEF - %concat:fpr(<16 x s8>) = G_CONCAT_VECTORS %a(<8 x s8>), %b(<8 x s8>) - $q0 = COPY %concat(<16 x s8>) + %a:fpr(<8 x i8>) = G_IMPLICIT_DEF + %b:fpr(<8 x i8>) = G_IMPLICIT_DEF + %concat:fpr(<16 x i8>) = G_CONCAT_VECTORS %a(<8 x i8>), %b(<8 x i8>) + $q0 = COPY %concat(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -113,10 +113,10 @@ body: | ; CHECK-NEXT: %concat:fpr128 = INSvi64lane [[INSERT_SUBREG1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY %concat ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %a:fpr(<8 x s8>) = COPY $d0 - %b:fpr(<8 x s8>) = COPY $d1 - %concat:fpr(<16 x s8>) = G_CONCAT_VECTORS %a(<8 x s8>), %b(<8 x s8>) - $q0 = COPY %concat(<16 x s8>) + %a:fpr(<8 x i8>) = COPY $d0 + %b:fpr(<8 x i8>) = COPY $d1 + %concat:fpr(<16 x i8>) = G_CONCAT_VECTORS %a(<8 x i8>), %b(<8 x i8>) + $q0 = COPY %concat(<16 x i8>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-const-pool.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-const-pool.mir index 041b76c54a5f8..25183359f4416 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-const-pool.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-const-pool.mir @@ -22,10 +22,10 @@ body: | ; CHECK: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<2 x s64>)) ; CHECK: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:fpr(s64) = G_FCONSTANT double 5.000000e-01 - %2:fpr(s64) = G_FCONSTANT double 1.600000e+01 - %1:fpr(<2 x s64>) = G_BUILD_VECTOR %2(s64), %3(s64) - G_STORE %1(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %3:fpr(f64) = G_FCONSTANT double 5.000000e-01 + %2:fpr(f64) = G_FCONSTANT double 1.600000e+01 + %1:fpr(<2 x f64>) = G_BUILD_VECTOR %2(f64), %3(f64) + G_STORE %1(<2 x f64>), %0(p0) :: (store (<2 x s64>)) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-const-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-const-vector.mir index 34ac115640814..68b9aabe5431c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-const-vector.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-const-vector.mir @@ -24,10 +24,10 @@ body: | ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<2 x s64>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:fpr(s64) = G_FCONSTANT double 5.000000e-01 - %2:fpr(s64) = G_FCONSTANT double 1.600000e+01 - %1:fpr(<2 x s64>) = G_BUILD_VECTOR %2(s64), %3(s64) - G_STORE %1(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %3:fpr(f64) = G_FCONSTANT double 5.000000e-01 + %2:fpr(f64) = G_FCONSTANT double 1.600000e+01 + %1:fpr(<2 x f64>) = G_BUILD_VECTOR %2(f64), %3(f64) + G_STORE %1(<2 x f64>), %0(p0) :: (store (<2 x s64>)) RET_ReallyLR ... @@ -54,10 +54,10 @@ body: | ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<4 x s32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:fpr(s32) = G_FCONSTANT float 5.000000e-01 - %2:fpr(s32) = G_FCONSTANT float 1.600000e+01 - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %3(s32), %3(s32), %3(s32) - G_STORE %1(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %3:fpr(f32) = G_FCONSTANT float 5.000000e-01 + %2:fpr(f32) = G_FCONSTANT float 1.600000e+01 + %1:fpr(<4 x f32>) = G_BUILD_VECTOR %2(f32), %3(f32), %3(f32), %3(f32) + G_STORE %1(<4 x f32>), %0(p0) :: (store (<4 x s32>)) RET_ReallyLR ... @@ -81,13 +81,13 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool) - ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<2 x s64>)) + ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:gpr(s64) = G_CONSTANT i64 67839 - %2:gpr(s64) = G_CONSTANT i64 12375 - %1:fpr(<2 x s64>) = G_BUILD_VECTOR %2(s64), %3(s64) - G_STORE %1(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %3:gpr(i64) = G_CONSTANT i64 67839 + %2:gpr(i64) = G_CONSTANT i64 12375 + %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(i64), %3(i64) + G_STORE %1(<2 x i64>), %0(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -111,13 +111,13 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool) - ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<4 x s32>)) + ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<4 x i32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = G_CONSTANT i32 67839 - %2:gpr(s32) = G_CONSTANT i32 12375 - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %3(s32), %2(s32), %3(s32) - G_STORE %1(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %3:gpr(i32) = G_CONSTANT i32 67839 + %2:gpr(i32) = G_CONSTANT i32 12375 + %1:fpr(<4 x i32>) = G_BUILD_VECTOR %2(i32), %3(i32), %2(i32), %3(i32) + G_STORE %1(<4 x i32>), %0(p0) :: (store (<4 x i32>)) RET_ReallyLR ... @@ -142,13 +142,13 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s64) from constant-pool) - ; CHECK-NEXT: STRDui [[LDRDui]], [[COPY]], 0 :: (store (<2 x s32>)) + ; CHECK-NEXT: STRDui [[LDRDui]], [[COPY]], 0 :: (store (<2 x i32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = G_CONSTANT i32 67839 - %2:gpr(s32) = G_CONSTANT i32 12375 - %1:fpr(<2 x s32>) = G_BUILD_VECTOR %2(s32), %3(s32) - G_STORE %1(<2 x s32>), %0(p0) :: (store (<2 x s32>)) + %3:gpr(i32) = G_CONSTANT i32 67839 + %2:gpr(i32) = G_CONSTANT i32 12375 + %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(i32), %3(i32) + G_STORE %1(<2 x i32>), %0(p0) :: (store (<2 x i32>)) RET_ReallyLR ... @@ -174,9 +174,9 @@ body: | ; CHECK-NEXT: STRQui [[MOVIv2d_ns]], [[COPY]], 0 :: (store (<4 x s32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %2:fpr(s32) = G_FCONSTANT float 0.000000e+00 - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %2(s32), %2(s32), %2(s32) - G_STORE %1(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %2:fpr(f32) = G_FCONSTANT float 0.000000e+00 + %1:fpr(<4 x f32>) = G_BUILD_VECTOR %2(f32), %2(f32), %2(f32), %2(f32) + G_STORE %1(<4 x f32>), %0(p0) :: (store (<4 x s32>)) RET_ReallyLR ... @@ -202,9 +202,9 @@ body: | ; CHECK-NEXT: STRQui [[MOVIv2d_ns]], [[COPY]], 0 :: (store (<4 x s32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %2:fpr(s32) = G_FCONSTANT float 0xFFFFFFFFE0000000 - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %2(s32), %2(s32), %2(s32) - G_STORE %1(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %2:fpr(f32) = G_FCONSTANT float 0xFFFFFFFFE0000000 + %1:fpr(<4 x f32>) = G_BUILD_VECTOR %2(f32), %2(f32), %2(f32), %2(f32) + G_STORE %1(<4 x f32>), %0(p0) :: (store (<4 x s32>)) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir index de1775ef8369a..95f860bafb2b9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir @@ -31,9 +31,9 @@ body: | ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY [[MOVi32imm]] ; CHECK-NEXT: $w0 = COPY [[COPY]] - %0:gpr(s8) = G_CONSTANT i8 42 - %1:gpr(s32) = G_ANYEXT %0(s8) - $w0 = COPY %1(s32) + %0:gpr(i8) = G_CONSTANT i8 42 + %1:gpr(i32) = G_ANYEXT %0(i8) + $w0 = COPY %1(i32) ... --- @@ -46,9 +46,9 @@ body: | ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY [[MOVi32imm]] ; CHECK-NEXT: $w0 = COPY [[COPY]] - %0:gpr(s16) = G_CONSTANT i16 42 - %1:gpr(s32) = G_ANYEXT %0(s16) - $w0 = COPY %1(s32) + %0:gpr(i16) = G_CONSTANT i16 42 + %1:gpr(i32) = G_ANYEXT %0(i16) + $w0 = COPY %1(i32) ... --- @@ -63,8 +63,8 @@ body: | ; CHECK-LABEL: name: const_s32 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 ; CHECK-NEXT: $w0 = COPY [[MOVi32imm]] - %0(s32) = G_CONSTANT i32 42 - $w0 = COPY %0(s32) + %0(i32) = G_CONSTANT i32 42 + $w0 = COPY %0(i32) ... --- @@ -79,8 +79,8 @@ body: | ; CHECK-LABEL: name: const_s64 ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 1234567890123 ; CHECK-NEXT: $x0 = COPY [[MOVi64imm]] - %0(s64) = G_CONSTANT i64 1234567890123 - $x0 = COPY %0(s64) + %0(i64) = G_CONSTANT i64 1234567890123 + $x0 = COPY %0(i64) ... --- @@ -95,8 +95,8 @@ body: | ; CHECK-LABEL: name: const_s32_zero ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $wzr ; CHECK-NEXT: $w0 = COPY [[COPY]] - %0(s32) = G_CONSTANT i32 0 - $w0 = COPY %0(s32) + %0(i32) = G_CONSTANT i32 0 + $w0 = COPY %0(i32) ... --- @@ -111,8 +111,8 @@ body: | ; CHECK-LABEL: name: const_s64_zero ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $xzr ; CHECK-NEXT: $x0 = COPY [[COPY]] - %0(s64) = G_CONSTANT i64 0 - $x0 = COPY %0(s64) + %0(i64) = G_CONSTANT i64 0 + $x0 = COPY %0(i64) ... --- @@ -201,8 +201,8 @@ body: | ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 42 ; CHECK-NEXT: $x0 = COPY [[MOVi64imm]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr(s64) = G_CONSTANT i64 42 - $x0 = COPY %0(s64) + %0:gpr(i64) = G_CONSTANT i64 42 + $x0 = COPY %0(i64) RET_ReallyLR implicit $x0 ... --- @@ -216,7 +216,7 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr(s64) = G_CONSTANT i64 42 - $x0 = COPY %0(s64) + %0:gpr(i64) = G_CONSTANT i64 42 + $x0 = COPY %0(i64) RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ext.mir index 4d76bdf405b3d..f041634351e24 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ext.mir @@ -21,10 +21,10 @@ body: | ; CHECK-NEXT: %v2:fpr64 = COPY $d1 ; CHECK-NEXT: %shuf:fpr64 = EXTv8i8 %v1, %v2, 3 ; CHECK-NEXT: $d0 = COPY %shuf - %v1:fpr(<8 x s8>) = COPY $d0 - %v2:fpr(<8 x s8>) = COPY $d1 - %3:gpr(s32) = G_CONSTANT i32 3 - %shuf:fpr(<8 x s8>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<8 x i8>) = COPY $d0 + %v2:fpr(<8 x i8>) = COPY $d1 + %3:gpr(i32) = G_CONSTANT i32 3 + %shuf:fpr(<8 x i8>) = G_EXT %v1, %v2, %3(i32) $d0 = COPY %shuf ... @@ -45,10 +45,10 @@ body: | ; CHECK-NEXT: %v2:fpr128 = COPY $q1 ; CHECK-NEXT: %shuf:fpr128 = EXTv16i8 %v1, %v2, 3 ; CHECK-NEXT: $q0 = COPY %shuf - %v1:fpr(<16 x s8>) = COPY $q0 - %v2:fpr(<16 x s8>) = COPY $q1 - %3:gpr(s32) = G_CONSTANT i32 3 - %shuf:fpr(<16 x s8>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<16 x i8>) = COPY $q0 + %v2:fpr(<16 x i8>) = COPY $q1 + %3:gpr(i32) = G_CONSTANT i32 3 + %shuf:fpr(<16 x i8>) = G_EXT %v1, %v2, %3(i32) $q0 = COPY %shuf ... @@ -69,10 +69,10 @@ body: | ; CHECK-NEXT: %v2:fpr64 = COPY $d1 ; CHECK-NEXT: %shuf:fpr64 = EXTv8i8 %v1, %v2, 6 ; CHECK-NEXT: $d0 = COPY %shuf - %v1:fpr(<4 x s16>) = COPY $d0 - %v2:fpr(<4 x s16>) = COPY $d1 - %3:gpr(s32) = G_CONSTANT i32 6 - %shuf:fpr(<4 x s16>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<4 x i16>) = COPY $d0 + %v2:fpr(<4 x i16>) = COPY $d1 + %3:gpr(i32) = G_CONSTANT i32 6 + %shuf:fpr(<4 x i16>) = G_EXT %v1, %v2, %3(i32) $d0 = COPY %shuf ... @@ -93,10 +93,10 @@ body: | ; CHECK-NEXT: %v2:fpr128 = COPY $q1 ; CHECK-NEXT: %shuf:fpr128 = EXTv16i8 %v2, %v1, 10 ; CHECK-NEXT: $q0 = COPY %shuf - %v1:fpr(<8 x s16>) = COPY $q0 - %v2:fpr(<8 x s16>) = COPY $q1 - %3:gpr(s32) = G_CONSTANT i32 10 - %shuf:fpr(<8 x s16>) = G_EXT %v2, %v1, %3(s32) + %v1:fpr(<8 x i16>) = COPY $q0 + %v2:fpr(<8 x i16>) = COPY $q1 + %3:gpr(i32) = G_CONSTANT i32 10 + %shuf:fpr(<8 x i16>) = G_EXT %v2, %v1, %3(i32) $q0 = COPY %shuf ... @@ -118,10 +118,10 @@ body: | ; CHECK-NEXT: %v2:fpr128 = COPY $q1 ; CHECK-NEXT: %shuf:fpr128 = EXTv16i8 %v1, %v2, 12 ; CHECK-NEXT: $q0 = COPY %shuf - %v1:fpr(<4 x s32>) = COPY $q0 - %v2:fpr(<4 x s32>) = COPY $q1 - %3:gpr(s32) = G_CONSTANT i32 12 - %shuf:fpr(<4 x s32>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<4 x i32>) = COPY $q0 + %v2:fpr(<4 x i32>) = COPY $q1 + %3:gpr(i32) = G_CONSTANT i32 12 + %shuf:fpr(<4 x i32>) = G_EXT %v1, %v2, %3(i32) $q0 = COPY %shuf ... @@ -142,10 +142,10 @@ body: | ; CHECK-NEXT: %v2:fpr64 = COPY $d1 ; CHECK-NEXT: %shuf:fpr64 = EXTv8i8 %v1, %v2, 2 ; CHECK-NEXT: $d0 = COPY %shuf - %v1:fpr(<2 x s32>) = COPY $d0 - %v2:fpr(<2 x s32>) = COPY $d1 - %3:gpr(s32) = G_CONSTANT i32 2 - %shuf:fpr(<2 x s32>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<2 x i32>) = COPY $d0 + %v2:fpr(<2 x i32>) = COPY $d1 + %3:gpr(i32) = G_CONSTANT i32 2 + %shuf:fpr(<2 x i32>) = G_EXT %v1, %v2, %3(i32) $d0 = COPY %shuf ... @@ -166,9 +166,9 @@ body: | ; CHECK-NEXT: %v2:fpr128 = COPY $q1 ; CHECK-NEXT: %shuf:fpr128 = EXTv16i8 %v1, %v2, 2 ; CHECK-NEXT: $q0 = COPY %shuf - %v1:fpr(<2 x s64>) = COPY $q0 - %v2:fpr(<2 x s64>) = COPY $q1 - %3:gpr(s32) = G_CONSTANT i32 2 - %shuf:fpr(<2 x s64>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<2 x i64>) = COPY $q0 + %v2:fpr(<2 x i64>) = COPY $q1 + %3:gpr(i32) = G_CONSTANT i32 2 + %shuf:fpr(<2 x i64>) = G_EXT %v1, %v2, %3(i32) $q0 = COPY %shuf ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-extload.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-extload.mir index 5ba0353e23f76..9b14cedb66263 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-extload.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-extload.mir @@ -22,11 +22,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_LOAD %0 :: (load (s16) from %ir.addr) - $w0 = COPY %1(s32) + %1:gpr(i32) = G_LOAD %0 :: (load (i16) from %ir.addr) + $w0 = COPY %1(i32) ... --- @@ -42,11 +42,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0:gpr(p0) = COPY $x0 - %1:gpr(s16) = G_LOAD %0 :: (load (s16) from %ir.addr) - %2:gpr(s32) = G_ANYEXT %1 - $w0 = COPY %2(s32) + %1:gpr(i16) = G_LOAD %0 :: (load (i16) from %ir.addr) + %2:gpr(i32) = G_ANYEXT %1 + $w0 = COPY %2(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt-with-extend.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt-with-extend.mir index 69f97f449b430..58b51556c26b9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt-with-extend.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt-with-extend.mir @@ -17,12 +17,12 @@ body: | ; CHECK-NEXT: [[SMOVvi32to64_:%[0-9]+]]:gpr64 = SMOVvi32to64 [[COPY]], 1 ; CHECK-NEXT: $x0 = COPY [[SMOVvi32to64_]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:fpr(<4 x s32>) = COPY $q0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<4 x s32>), %3(s64) - %5:gpr(s32) = COPY %2(s32) - %4:gpr(s64) = G_SEXT %5(s32) - $x0 = COPY %4(s64) + %0:fpr(<4 x i32>) = COPY $q0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<4 x i32>), %3(i64) + %5:gpr(i32) = COPY %2(i32) + %4:gpr(i64) = G_SEXT %5(i32) + $x0 = COPY %4(i64) RET_ReallyLR implicit $x0 ... @@ -44,12 +44,12 @@ body: | ; CHECK-NEXT: [[SMOVvi32to64_:%[0-9]+]]:gpr64 = SMOVvi32to64 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $x0 = COPY [[SMOVvi32to64_]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:fpr(<2 x s32>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<2 x s32>), %3(s64) - %5:gpr(s32) = COPY %2(s32) - %4:gpr(s64) = G_SEXT %5(s32) - $x0 = COPY %4(s64) + %0:fpr(<2 x i32>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<2 x i32>), %3(i64) + %5:gpr(i32) = COPY %2(i32) + %4:gpr(i64) = G_SEXT %5(i32) + $x0 = COPY %4(i64) RET_ReallyLR implicit $x0 ... @@ -70,12 +70,12 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[UMOVvi32_]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:fpr(<4 x s32>) = COPY $q0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<4 x s32>), %3(s64) - %5:gpr(s32) = COPY %2(s32) - %4:gpr(s64) = G_ZEXT %5(s32) - $x0 = COPY %4(s64) + %0:fpr(<4 x i32>) = COPY $q0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<4 x i32>), %3(i64) + %5:gpr(i32) = COPY %2(i32) + %4:gpr(i64) = G_ZEXT %5(i32) + $x0 = COPY %4(i64) RET_ReallyLR implicit $x0 ... @@ -98,12 +98,12 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[UMOVvi32_]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:fpr(<2 x s32>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<2 x s32>), %3(s64) - %5:gpr(s32) = COPY %2(s32) - %4:gpr(s64) = G_ZEXT %5(s32) - $x0 = COPY %4(s64) + %0:fpr(<2 x i32>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<2 x i32>), %3(i64) + %5:gpr(i32) = COPY %2(i32) + %4:gpr(i64) = G_ZEXT %5(i32) + $x0 = COPY %4(i64) RET_ReallyLR implicit $x0 ... @@ -123,12 +123,12 @@ body: | ; CHECK-NEXT: [[SMOVvi16to32_:%[0-9]+]]:gpr32 = SMOVvi16to32 [[COPY]], 1 ; CHECK-NEXT: $w0 = COPY [[SMOVvi16to32_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s16>) = COPY $q0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %4(s64) - %6:gpr(s16) = COPY %3(s16) - %5:gpr(s32) = G_SEXT %6(s16) - $w0 = COPY %5(s32) + %0:fpr(<8 x i16>) = COPY $q0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %4(i64) + %6:gpr(i16) = COPY %3(i16) + %5:gpr(i32) = G_SEXT %6(i16) + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... @@ -148,12 +148,12 @@ body: | ; CHECK-NEXT: [[UMOVvi16_:%[0-9]+]]:gpr32 = UMOVvi16 [[COPY]], 1 ; CHECK-NEXT: $w0 = COPY [[UMOVvi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s16>) = COPY $q0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %4(s64) - %6:gpr(s16) = COPY %3(s16) - %5:gpr(s32) = G_ZEXT %6(s16) - $w0 = COPY %5(s32) + %0:fpr(<8 x i16>) = COPY $q0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %4(i64) + %6:gpr(i16) = COPY %3(i16) + %5:gpr(i32) = G_ZEXT %6(i16) + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... @@ -175,12 +175,12 @@ body: | ; CHECK-NEXT: [[SMOVvi16to32_:%[0-9]+]]:gpr32 = SMOVvi16to32 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $w0 = COPY [[SMOVvi16to32_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<4 x s16>) = COPY $d0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<4 x s16>), %4(s64) - %6:gpr(s16) = COPY %3(s16) - %5:gpr(s32) = G_SEXT %6(s16) - $w0 = COPY %5(s32) + %0:fpr(<4 x i16>) = COPY $d0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<4 x i16>), %4(i64) + %6:gpr(i16) = COPY %3(i16) + %5:gpr(i32) = G_SEXT %6(i16) + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... @@ -202,12 +202,12 @@ body: | ; CHECK-NEXT: [[UMOVvi16_:%[0-9]+]]:gpr32 = UMOVvi16 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $w0 = COPY [[UMOVvi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<4 x s16>) = COPY $d0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<4 x s16>), %4(s64) - %6:gpr(s16) = COPY %3(s16) - %5:gpr(s32) = G_ZEXT %6(s16) - $w0 = COPY %5(s32) + %0:fpr(<4 x i16>) = COPY $d0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<4 x i16>), %4(i64) + %6:gpr(i16) = COPY %3(i16) + %5:gpr(i32) = G_ZEXT %6(i16) + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... @@ -227,12 +227,12 @@ body: | ; CHECK-NEXT: [[SMOVvi8to32_:%[0-9]+]]:gpr32 = SMOVvi8to32 [[COPY]], 1 ; CHECK-NEXT: $w0 = COPY [[SMOVvi8to32_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<16 x s8>) = COPY $q0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<16 x s8>), %4(s64) - %7:gpr(s8) = COPY %3(s8) - %6:gpr(s32) = G_SEXT %7(s8) - $w0 = COPY %6(s32) + %0:fpr(<16 x i8>) = COPY $q0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<16 x i8>), %4(i64) + %7:gpr(i8) = COPY %3(i8) + %6:gpr(i32) = G_SEXT %7(i8) + $w0 = COPY %6(i32) RET_ReallyLR implicit $w0 ... --- @@ -251,12 +251,12 @@ body: | ; CHECK-NEXT: [[UMOVvi8_:%[0-9]+]]:gpr32 = UMOVvi8 [[COPY]], 1 ; CHECK-NEXT: $w0 = COPY [[UMOVvi8_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<16 x s8>) = COPY $q0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<16 x s8>), %4(s64) - %7:gpr(s8) = COPY %3(s8) - %6:gpr(s32) = G_ZEXT %7(s8) - $w0 = COPY %6(s32) + %0:fpr(<16 x i8>) = COPY $q0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<16 x i8>), %4(i64) + %7:gpr(i8) = COPY %3(i8) + %6:gpr(i32) = G_ZEXT %7(i8) + $w0 = COPY %6(i32) RET_ReallyLR implicit $w0 ... @@ -278,12 +278,12 @@ body: | ; CHECK-NEXT: [[SMOVvi8to32_:%[0-9]+]]:gpr32 = SMOVvi8to32 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $w0 = COPY [[SMOVvi8to32_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s8>) = COPY $d0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<8 x s8>), %4(s64) - %7:gpr(s8) = COPY %3(s8) - %6:gpr(s32) = G_SEXT %7(s8) - $w0 = COPY %6(s32) + %0:fpr(<8 x i8>) = COPY $d0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<8 x i8>), %4(i64) + %7:gpr(i8) = COPY %3(i8) + %6:gpr(i32) = G_SEXT %7(i8) + $w0 = COPY %6(i32) RET_ReallyLR implicit $w0 ... --- @@ -304,12 +304,12 @@ body: | ; CHECK-NEXT: [[UMOVvi8_:%[0-9]+]]:gpr32 = UMOVvi8 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $w0 = COPY [[UMOVvi8_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s8>) = COPY $d0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<8 x s8>), %4(s64) - %7:gpr(s8) = COPY %3(s8) - %6:gpr(s32) = G_ZEXT %7(s8) - $w0 = COPY %6(s32) + %0:fpr(<8 x i8>) = COPY $d0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<8 x i8>), %4(i64) + %7:gpr(i8) = COPY %3(i8) + %6:gpr(i32) = G_ZEXT %7(i8) + $w0 = COPY %6(i32) RET_ReallyLR implicit $w0 ... @@ -326,11 +326,11 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[COPY]], %subreg.bsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] - %5:fpr(<16 x s8>) = G_IMPLICIT_DEF - %12:gpr(s64) = G_CONSTANT i64 0 - %4:fpr(s8) = G_EXTRACT_VECTOR_ELT %5(<16 x s8>), %12(s64) - %11:gpr(s8) = COPY %4(s8) - %8:gpr(s16) = G_ANYEXT %11(s8) - %ext:gpr(s32) = G_ANYEXT %8(s16) - $w0 = COPY %ext(s32) + %5:fpr(<16 x i8>) = G_IMPLICIT_DEF + %12:gpr(i64) = G_CONSTANT i64 0 + %4:fpr(i8) = G_EXTRACT_VECTOR_ELT %5(<16 x i8>), %12(i64) + %11:gpr(i8) = COPY %4(i8) + %8:gpr(i16) = G_ANYEXT %11(i8) + %ext:gpr(i32) = G_ANYEXT %8(i16) + $w0 = COPY %ext(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt.mir index 375506f300de0..0f716ae7ab6e8 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt.mir @@ -25,11 +25,11 @@ body: | ; CHECK-NEXT: [[DUPi32_:%[0-9]+]]:fpr32 = DUPi32 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $s0 = COPY [[DUPi32_]] ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:fpr(<2 x s32>) = COPY $d0 - %2:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<2 x s32>), %3(s64) - $s0 = COPY %1(s32) + %0:fpr(<2 x i32>) = COPY $d0 + %2:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<2 x i32>), %3(i64) + $s0 = COPY %1(i32) RET_ReallyLR implicit $s0 ... @@ -49,11 +49,11 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]].ssub ; CHECK-NEXT: $s0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:fpr(<2 x s32>) = COPY $d0 - %2:gpr(s64) = G_CONSTANT i64 0 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<2 x s32>), %3(s64) - $s0 = COPY %1(s32) + %0:fpr(<2 x i32>) = COPY $d0 + %2:gpr(i64) = G_CONSTANT i64 0 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<2 x i32>), %3(i64) + $s0 = COPY %1(i32) RET_ReallyLR implicit $s0 ... @@ -79,11 +79,11 @@ body: | ; CHECK-NEXT: [[DUPi64_:%[0-9]+]]:fpr64 = DUPi64 [[COPY]], 2 ; CHECK-NEXT: $d0 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s64>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 2 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s64) = G_EXTRACT_VECTOR_ELT %0(<2 x s64>), %3(s64) - $d0 = COPY %1(s64) + %0:fpr(<2 x i64>) = COPY $q0 + %2:gpr(i64) = G_CONSTANT i64 2 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i64) = G_EXTRACT_VECTOR_ELT %0(<2 x i64>), %3(i64) + $d0 = COPY %1(i64) RET_ReallyLR implicit $d0 ... @@ -111,11 +111,11 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<4 x s16>) = COPY $d0 - %2:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<4 x s16>), %3(s64) - $h0 = COPY %1(s16) + %0:fpr(<4 x i16>) = COPY $d0 + %2:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<4 x i16>), %3(i64) + $h0 = COPY %1(i16) RET_ReallyLR implicit $h0 ... @@ -135,11 +135,11 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[COPY]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<8 x s16>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %3(s64) - $h0 = COPY %1(s16) + %0:fpr(<8 x i16>) = COPY $q0 + %2:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %3(i64) + $h0 = COPY %1(i16) RET_ReallyLR implicit $h0 ... @@ -159,12 +159,12 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[COPY]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s64) = G_ZEXT %1 - %3:fpr(s64) = COPY %2(s64) - %4:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %3(s64) - $h0 = COPY %4(s16) + %0:fpr(<8 x i16>) = COPY $q0 + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i64) = G_ZEXT %1 + %3:fpr(i64) = COPY %2(i64) + %4:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %3(i64) + $h0 = COPY %4(i16) RET_ReallyLR implicit $h0 ... @@ -184,12 +184,12 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[COPY]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s64) = G_SEXT %1 - %3:fpr(s64) = COPY %2(s64) - %4:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %3(s64) - $h0 = COPY %4(s16) + %0:fpr(<8 x i16>) = COPY $q0 + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i64) = G_SEXT %1 + %3:fpr(i64) = COPY %2(i64) + %4:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %3(i64) + $h0 = COPY %4(i16) RET_ReallyLR implicit $h0 ... @@ -209,13 +209,13 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[COPY]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:gpr(s64) = G_CONSTANT i64 1 - %2:gpr(s32) = G_TRUNC %1 - %3:gpr(s64) = G_SEXT %2 - %4:fpr(s64) = COPY %3(s64) - %5:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %4(s64) - $h0 = COPY %5(s16) + %0:fpr(<8 x i16>) = COPY $q0 + %1:gpr(i64) = G_CONSTANT i64 1 + %2:gpr(i32) = G_TRUNC %1 + %3:gpr(i64) = G_SEXT %2 + %4:fpr(i64) = COPY %3(i64) + %5:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %4(i64) + $h0 = COPY %5(i16) RET_ReallyLR implicit $h0 ... --- @@ -237,12 +237,12 @@ body: | ; CHECK-NEXT: [[UMOVvi8_:%[0-9]+]]:gpr32 = UMOVvi8 [[COPY]], 0 ; CHECK-NEXT: $w0 = COPY [[UMOVvi8_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<16 x s8>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 0 - %1:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<16 x s8>), %2(s64) - %4:gpr(s8) = COPY %1(s8) - %3:gpr(s32) = G_ANYEXT %4(s8) - $w0 = COPY %3(s32) + %0:fpr(<16 x i8>) = COPY $q0 + %2:gpr(i64) = G_CONSTANT i64 0 + %1:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<16 x i8>), %2(i64) + %4:gpr(i8) = COPY %1(i8) + %3:gpr(i32) = G_ANYEXT %4(i8) + $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 ... @@ -267,12 +267,12 @@ body: | ; CHECK-NEXT: [[UMOVvi8_:%[0-9]+]]:gpr32 = UMOVvi8 [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $w0 = COPY [[UMOVvi8_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s8>) = COPY $d0 - %2:gpr(s64) = G_CONSTANT i64 0 - %1:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<8 x s8>), %2(s64) - %4:gpr(s8) = COPY %1(s8) - %3:gpr(s32) = G_ANYEXT %4(s8) - $w0 = COPY %3(s32) + %0:fpr(<8 x i8>) = COPY $d0 + %2:gpr(i64) = G_CONSTANT i64 0 + %1:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<8 x i8>), %2(i64) + %4:gpr(i8) = COPY %1(i8) + %3:gpr(i32) = G_ANYEXT %4(i8) + $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 ... @@ -294,8 +294,8 @@ body: | ; CHECK-NEXT: $d0 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:fpr(<2 x p0>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 1 - %1:fpr(p0) = G_EXTRACT_VECTOR_ELT %0(<2 x p0>), %2(s64) + %2:gpr(i64) = G_CONSTANT i64 1 + %1:fpr(p0) = G_EXTRACT_VECTOR_ELT %0(<2 x p0>), %2(i64) $d0 = COPY %1(p0) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract.mir index d3795e36bd049..d7f67dc06aab3 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract.mir @@ -19,11 +19,11 @@ body: | ; CHECK-NEXT: $d3 = COPY [[COPY1]] ; CHECK-NEXT: $d4 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d3 - %0:fpr(s128) = COPY $q0 - %2:fpr(s64) = G_EXTRACT %0(s128), 0 - %3:fpr(s64) = G_EXTRACT %0(s128), 64 - $d3 = COPY %2(s64) - $d4 = COPY %3(s64) + %0:fpr(i128) = COPY $q0 + %2:fpr(i64) = G_EXTRACT %0(i128), 0 + %3:fpr(i64) = G_EXTRACT %0(i128), 64 + $d3 = COPY %2(i64) + $d4 = COPY %3(i64) RET_ReallyLR implicit $d3 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-fp-index-load.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-fp-index-load.mir index b485cd2e88edd..0af08af070701 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-fp-index-load.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-fp-index-load.mir @@ -16,15 +16,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr16 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $h0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s16), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s8)) - $h0 = COPY %2(s16) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i16), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i8)) + $h0 = COPY %2(i16) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -43,15 +43,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $s0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s8)) - $s0 = COPY %2(s32) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i8)) + $s0 = COPY %2(i32) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -70,15 +70,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s8)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i8)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -97,15 +97,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpost [[COPY]], 4 :: (load (s16)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpost [[COPY]], 4 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG %4, %subreg.hsub ; CHECK-NEXT: $s0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s16)) - $s0 = COPY %2(s32) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i16)) + $s0 = COPY %2(i32) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -124,15 +124,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpost [[COPY]], 4 :: (load (s16)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpost [[COPY]], 4 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.hsub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s16)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i16)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -151,15 +151,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr32 = LDRSpost [[COPY]], 4 :: (load (s32)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr32 = LDRSpost [[COPY]], 4 :: (load (i32)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.ssub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s32)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i32)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -178,15 +178,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr16 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $h0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s16), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s8)) - $h0 = COPY %2(s16) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i16), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i8)) + $h0 = COPY %2(i16) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -205,15 +205,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $s0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s8)) - $s0 = COPY %2(s32) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i8)) + $s0 = COPY %2(i32) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -232,15 +232,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s8)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i8)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -259,15 +259,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpre [[COPY]], 4 :: (load (s16)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpre [[COPY]], 4 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG %4, %subreg.hsub ; CHECK-NEXT: $s0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s16)) - $s0 = COPY %2(s32) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i16)) + $s0 = COPY %2(i32) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -286,15 +286,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpre [[COPY]], 4 :: (load (s16)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpre [[COPY]], 4 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.hsub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s16)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i16)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -313,15 +313,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr32 = LDRSpre [[COPY]], 4 :: (load (s32)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr32 = LDRSpre [[COPY]], 4 :: (load (i32)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.ssub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s32)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i32)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-frint-nofp16.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-frint-nofp16.mir index 1ca06aa2c70ea..b047f7acac6b9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-frint-nofp16.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-frint-nofp16.mir @@ -173,7 +173,7 @@ body: | ; CHECK-NEXT: $q0 = COPY [[INSvi16lane6]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:fpr(<8 x f16>) = COPY $q0 - %2:fpr(f16), %3:fpr(f16), %4:fpr(f16), %5:fpr(f16), %6:fpr(f16), %7:fpr(f16), %8:fpr(f16), %9:fpr(f16) = G_UNMERGE_VALUES %0(<8 x s16>) + %2:fpr(f16), %3:fpr(f16), %4:fpr(f16), %5:fpr(f16), %6:fpr(f16), %7:fpr(f16), %8:fpr(f16), %9:fpr(f16) = G_UNMERGE_VALUES %0(<8 x f16>) %32:fpr(f32) = G_FPEXT %2(f16) %33:fpr(f32) = G_FRINT %32 %10:fpr(f16) = G_FPTRUNC %33(f32) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-large.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-large.mir index caa1f7e7ef19b..a6521f730bb9c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-large.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-large.mir @@ -41,9 +41,9 @@ body: | ; STATIC-NEXT: [[MOVKXi4:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi3]], target-flags(aarch64-g2, aarch64-nc) @foo2, 32 ; STATIC-NEXT: [[MOVKXi5:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi4]], target-flags(aarch64-g3) @foo2, 48 ; STATIC-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[MOVKXi5]] - ; STATIC-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (s32) into %ir.retval) - ; STATIC-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32) from @foo1) - ; STATIC-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (s32) from @foo2) + ; STATIC-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (i32) into %ir.retval) + ; STATIC-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32) from @foo1) + ; STATIC-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (i32) from @foo2) ; STATIC-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRWui]], [[LDRWui1]] ; STATIC-NEXT: $w0 = COPY [[ADDWrr]] ; STATIC-NEXT: RET_ReallyLR implicit $w0 @@ -53,21 +53,21 @@ body: | ; PIC-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY [[MOVaddr]] ; PIC-NEXT: [[MOVaddr1:%[0-9]+]]:gpr64common = MOVaddr target-flags(aarch64-page) @foo2, target-flags(aarch64-pageoff, aarch64-nc) @foo2 ; PIC-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[MOVaddr1]] - ; PIC-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (s32) into %ir.retval) - ; PIC-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32) from @foo1) - ; PIC-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (s32) from @foo2) + ; PIC-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (i32) into %ir.retval) + ; PIC-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32) from @foo1) + ; PIC-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (i32) from @foo2) ; PIC-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRWui]], [[LDRWui1]] ; PIC-NEXT: $w0 = COPY [[ADDWrr]] ; PIC-NEXT: RET_ReallyLR implicit $w0 - %1:gpr(s32) = G_CONSTANT i32 0 + %1:gpr(i32) = G_CONSTANT i32 0 %4:gpr(p0) = G_GLOBAL_VALUE @foo1 %3:gpr(p0) = COPY %4(p0) %7:gpr(p0) = G_GLOBAL_VALUE @foo2 %6:gpr(p0) = COPY %7(p0) %0:gpr(p0) = G_FRAME_INDEX %stack.0.retval - G_STORE %1(s32), %0(p0) :: (store (s32) into %ir.retval) - %2:gpr(i32) = G_LOAD %3(p0) :: (load (s32) from @foo1) - %5:gpr(i32) = G_LOAD %6(p0) :: (load (s32) from @foo2) + G_STORE %1(i32), %0(p0) :: (store (i32) into %ir.retval) + %2:gpr(i32) = G_LOAD %3(p0) :: (load (i32) from @foo1) + %5:gpr(i32) = G_LOAD %6(p0) :: (load (i32) from @foo2) %8:gpr(i32) = G_ADD %2, %5 $w0 = COPY %8(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir index 65e85f37c21e3..1ba04037aa133 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir @@ -34,21 +34,21 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY [[ADR]] ; CHECK-NEXT: [[ADR1:%[0-9]+]]:gpr64 = ADR @foo2 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[ADR1]] - ; CHECK-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (s32) into %ir.retval) - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32) from @foo1) - ; CHECK-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (s32) from @foo2) + ; CHECK-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (i32) into %ir.retval) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32) from @foo1) + ; CHECK-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (i32) from @foo2) ; CHECK-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRWui]], [[LDRWui1]] ; CHECK-NEXT: $w0 = COPY [[ADDWrr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %1:gpr(s32) = G_CONSTANT i32 0 + %1:gpr(i32) = G_CONSTANT i32 0 %4:gpr(p0) = G_GLOBAL_VALUE @foo1 %3:gpr(p0) = COPY %4(p0) %7:gpr(p0) = G_GLOBAL_VALUE @foo2 %6:gpr(p0) = COPY %7(p0) %0:gpr(p0) = G_FRAME_INDEX %stack.0.retval - G_STORE %1(s32), %0(p0) :: (store (s32) into %ir.retval) - %2:gpr(i32) = G_LOAD %3(p0) :: (load (s32) from @foo1) - %5:gpr(i32) = G_LOAD %6(p0) :: (load (s32) from @foo2) + G_STORE %1(i32), %0(p0) :: (store (i32) into %ir.retval) + %2:gpr(i32) = G_LOAD %3(p0) :: (load (i32) from @foo1) + %5:gpr(i32) = G_LOAD %6(p0) :: (load (i32) from @foo2) %8:gpr(i32) = G_ADD %2, %5 $w0 = COPY %8(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir index 99e864a287f2b..d7efa669bf35c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir @@ -19,9 +19,9 @@ body: | ; CHECK-NEXT: %copy:gpr32 = COPY $w0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:gpr(s32) = COPY $w0 - %copy_assert_zext:gpr(s32) = G_ASSERT_ZEXT %copy, 16 - $w1 = COPY %copy_assert_zext(s32) + %copy:gpr(i32) = COPY $w0 + %copy_assert_zext:gpr(i32) = G_ASSERT_ZEXT %copy, 16 + $w1 = COPY %copy_assert_zext(i32) RET_ReallyLR implicit $w1 ... @@ -40,9 +40,9 @@ body: | ; CHECK-NEXT: %copy:fpr32 = COPY $s0 ; CHECK-NEXT: $s1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $s1 - %copy:fpr(s32) = COPY $s0 - %copy_assert_zext:fpr(s32) = G_ASSERT_ZEXT %copy, 16 - $s1 = COPY %copy_assert_zext(s32) + %copy:fpr(i32) = COPY $s0 + %copy_assert_zext:fpr(i32) = G_ASSERT_ZEXT %copy, 16 + $s1 = COPY %copy_assert_zext(i32) RET_ReallyLR implicit $s1 ... @@ -61,9 +61,9 @@ body: | ; CHECK-NEXT: %copy:fpr32 = COPY $s0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:fpr(s32) = COPY $s0 - %copy_assert_zext:fpr(s32) = G_ASSERT_ZEXT %copy, 16 - $w1 = COPY %copy_assert_zext(s32) + %copy:fpr(i32) = COPY $s0 + %copy_assert_zext:fpr(i32) = G_ASSERT_ZEXT %copy, 16 + $w1 = COPY %copy_assert_zext(i32) RET_ReallyLR implicit $w1 ... @@ -85,10 +85,10 @@ body: | ; CHECK-NEXT: %copy_with_rc:gpr32sp = COPY $w2 ; CHECK-NEXT: $w1 = COPY %copy_with_rc ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:gpr(s32) = COPY $w0 - %copy_assert_zext:gpr(s32) = G_ASSERT_ZEXT %copy, 16 - %copy_with_rc:gpr32sp(s32) = COPY $w2 - $w1 = COPY %copy_with_rc(s32) + %copy:gpr(i32) = COPY $w0 + %copy_assert_zext:gpr(i32) = G_ASSERT_ZEXT %copy, 16 + %copy_with_rc:gpr32sp(i32) = COPY $w2 + $w1 = COPY %copy_with_rc(i32) RET_ReallyLR implicit $w1 ... @@ -107,9 +107,9 @@ body: | ; CHECK-NEXT: %copy:gpr32 = COPY $w0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:gpr(s32) = COPY $w0 - %copy_assert_sext:gpr(s32) = G_ASSERT_SEXT %copy, 16 - $w1 = COPY %copy_assert_sext(s32) + %copy:gpr(i32) = COPY $w0 + %copy_assert_sext:gpr(i32) = G_ASSERT_SEXT %copy, 16 + $w1 = COPY %copy_assert_sext(i32) RET_ReallyLR implicit $w1 ... @@ -128,9 +128,9 @@ body: | ; CHECK-NEXT: %copy:fpr32 = COPY $s0 ; CHECK-NEXT: $s1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $s1 - %copy:fpr(s32) = COPY $s0 - %copy_assert_sext:fpr(s32) = G_ASSERT_SEXT %copy, 16 - $s1 = COPY %copy_assert_sext(s32) + %copy:fpr(i32) = COPY $s0 + %copy_assert_sext:fpr(i32) = G_ASSERT_SEXT %copy, 16 + $s1 = COPY %copy_assert_sext(i32) RET_ReallyLR implicit $s1 ... @@ -149,9 +149,9 @@ body: | ; CHECK-NEXT: %copy:fpr32 = COPY $s0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:fpr(s32) = COPY $s0 - %copy_assert_sext:fpr(s32) = G_ASSERT_SEXT %copy, 16 - $w1 = COPY %copy_assert_sext(s32) + %copy:fpr(i32) = COPY $s0 + %copy_assert_sext:fpr(i32) = G_ASSERT_SEXT %copy, 16 + $w1 = COPY %copy_assert_sext(i32) RET_ReallyLR implicit $w1 ... @@ -173,8 +173,8 @@ body: | ; CHECK-NEXT: %copy_with_rc:gpr32sp = COPY $w2 ; CHECK-NEXT: $w1 = COPY %copy_with_rc ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:gpr(s32) = COPY $w0 - %copy_assert_sext:gpr(s32) = G_ASSERT_SEXT %copy, 16 - %copy_with_rc:gpr32sp(s32) = COPY $w2 - $w1 = COPY %copy_with_rc(s32) + %copy:gpr(i32) = COPY $w0 + %copy_assert_sext:gpr(i32) = G_ASSERT_SEXT %copy, 16 + %copy_with_rc:gpr32sp(i32) = COPY $w2 + $w1 = COPY %copy_with_rc(i32) RET_ReallyLR implicit $w1 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir index 07e2e189b4c03..798326206bd28 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir @@ -41,8 +41,8 @@ body: | ; CHECK-TINY-NEXT: {{ $}} ; CHECK-TINY-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm -1234 ; CHECK-TINY-NEXT: $w0 = COPY [[MOVi32imm]] - %0(s32) = G_CONSTANT i32 -1234 - $w0 = COPY %0(s32) + %0(i32) = G_CONSTANT i32 -1234 + $w0 = COPY %0(i32) ... --- @@ -71,8 +71,8 @@ body: | ; CHECK-TINY-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1234 ; CHECK-TINY-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-TINY-NEXT: $x0 = COPY [[SUBREG_TO_REG]] - %0(s64) = G_CONSTANT i64 1234 - $x0 = COPY %0(s64) + %0(i64) = G_CONSTANT i64 1234 + $x0 = COPY %0(i64) ... # 64b FP immediates need to be loaded. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-extract.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-extract.mir index 78d86a6821877..04d5ce0160b73 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-extract.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-extract.mir @@ -21,13 +21,13 @@ body: | ; CHECK-NEXT: [[BFMXri1:%[0-9]+]]:gpr64 = BFMXri [[DEF]], [[SUBREG_TO_REG1]], 51, 31 ; CHECK-NEXT: $x0 = COPY [[BFMXri]] ; CHECK-NEXT: $x1 = COPY [[BFMXri1]] - %0:gpr(s32) = COPY $w0 + %0:gpr(i32) = COPY $w0 - %1:gpr(s64) = G_IMPLICIT_DEF + %1:gpr(i64) = G_IMPLICIT_DEF - %2:gpr(s64) = G_INSERT %1, %0, 0 + %2:gpr(i64) = G_INSERT %1, %0, 0 - %3:gpr(s64) = G_INSERT %1, %0, 13 + %3:gpr(i64) = G_INSERT %1, %0, 13 $x0 = COPY %2 $x1 = COPY %3 @@ -50,14 +50,14 @@ body: | ; CHECK-NEXT: [[BFMWri1:%[0-9]+]]:gpr32 = BFMWri [[BFMWri]], [[COPY]], 16, 15 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[BFMWri1]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] - %1:gpr(s32) = COPY $w0 - %2:gpr(s32) = COPY $w1 - %3:gpr(s16) = G_TRUNC %1(s32) - %4:gpr(s16) = G_TRUNC %1(s32) - %5:gpr(s32) = G_IMPLICIT_DEF - %6:gpr(s32) = G_INSERT %5, %3(s16), 0 - %7:gpr(s32) = G_INSERT %6, %4(s16), 16 - %0:gpr(s32) = COPY %7(s32) + %1:gpr(i32) = COPY $w0 + %2:gpr(i32) = COPY $w1 + %3:gpr(i16) = G_TRUNC %1(i32) + %4:gpr(i16) = G_TRUNC %1(i32) + %5:gpr(i32) = G_IMPLICIT_DEF + %6:gpr(i32) = G_INSERT %5, %3(i16), 0 + %7:gpr(i32) = G_INSERT %6, %4(i16), 16 + %0:gpr(i32) = COPY %7(i32) $w0 = COPY %0 ... @@ -80,11 +80,11 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[UBFMXri1]].sub_32 ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: $w1 = COPY [[COPY2]] - %0:gpr(s64) = COPY $x0 + %0:gpr(i64) = COPY $x0 - %1:gpr(s32) = G_EXTRACT %0, 0 + %1:gpr(i32) = G_EXTRACT %0, 0 - %2:gpr(s32) = G_EXTRACT %0, 13 + %2:gpr(i32) = G_EXTRACT %0, 13 $w0 = COPY %1 $w1 = COPY %2 @@ -111,11 +111,11 @@ body: | ; CHECK-NEXT: [[COPY3:%[0-9]+]]:fpr32 = COPY [[UBFMWri1]] ; CHECK-NEXT: [[COPY4:%[0-9]+]]:fpr16 = COPY [[COPY3]].hsub ; CHECK-NEXT: $h1 = COPY [[COPY4]] - %0:gpr(s32) = COPY $w0 + %0:gpr(i32) = COPY $w0 - %1:gpr(s16) = G_EXTRACT %0, 0 + %1:gpr(i16) = G_EXTRACT %0, 0 - %2:gpr(s16) = G_EXTRACT %0, 15 + %2:gpr(i16) = G_EXTRACT %0, 15 $h0 = COPY %1 $h1 = COPY %2 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir index e761c3a808980..e6252a30f2651 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir @@ -18,13 +18,13 @@ body: | ; CHECK-NEXT: [[INSvi8gpr:%[0-9]+]]:fpr128 = INSvi8gpr [[COPY1]], 1, [[COPY]] ; CHECK-NEXT: $q0 = COPY [[INSvi8gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s8) = G_TRUNC %0 - %1:fpr(<16 x s8>) = COPY $q1 - %3:gpr(s64) = G_CONSTANT i64 1 - %4:gpr(s32) = G_ANYEXT %trunc - %2:fpr(<16 x s8>) = G_INSERT_VECTOR_ELT %1, %4:gpr(s32), %3:gpr(s64) - $q0 = COPY %2(<16 x s8>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i8) = G_TRUNC %0 + %1:fpr(<16 x i8>) = COPY $q1 + %3:gpr(i64) = G_CONSTANT i64 1 + %4:gpr(i32) = G_ANYEXT %trunc + %2:fpr(<16 x i8>) = G_INSERT_VECTOR_ELT %1, %4:gpr(i32), %3:gpr(i64) + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -49,12 +49,12 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi8gpr]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s8) = G_TRUNC %0 - %1:fpr(<8 x s8>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<8 x s8>) = G_INSERT_VECTOR_ELT %1, %trunc(s8), %3(s64) - $d0 = COPY %2(<8 x s8>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i8) = G_TRUNC %0 + %1:fpr(<8 x i8>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<8 x i8>) = G_INSERT_VECTOR_ELT %1, %trunc(i8), %3(i64) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -79,13 +79,13 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi8gpr]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s8) = G_TRUNC %0 - %1:fpr(<8 x s8>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %4:gpr(s32) = G_ANYEXT %trunc - %2:fpr(<8 x s8>) = G_INSERT_VECTOR_ELT %1, %4(s32), %3(s64) - $d0 = COPY %2(<8 x s8>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i8) = G_TRUNC %0 + %1:fpr(<8 x i8>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %4:gpr(i32) = G_ANYEXT %trunc + %2:fpr(<8 x i8>) = G_INSERT_VECTOR_ELT %1, %4(i32), %3(i64) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -107,13 +107,13 @@ body: | ; CHECK-NEXT: [[INSvi16gpr:%[0-9]+]]:fpr128 = INSvi16gpr [[COPY1]], 1, [[COPY]] ; CHECK-NEXT: $q0 = COPY [[INSvi16gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s16) = G_TRUNC %0 - %1:fpr(<8 x s16>) = COPY $q1 - %3:gpr(s64) = G_CONSTANT i64 1 - %4:gpr(s32) = G_ANYEXT %trunc - %2:fpr(<8 x s16>) = G_INSERT_VECTOR_ELT %1, %4:gpr(s32), %3:gpr(s64) - $q0 = COPY %2(<8 x s16>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i16) = G_TRUNC %0 + %1:fpr(<8 x i16>) = COPY $q1 + %3:gpr(i64) = G_CONSTANT i64 1 + %4:gpr(i32) = G_ANYEXT %trunc + %2:fpr(<8 x i16>) = G_INSERT_VECTOR_ELT %1, %4:gpr(i32), %3:gpr(i64) + $q0 = COPY %2(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -165,11 +165,11 @@ body: | ; CHECK-NEXT: [[INSvi32lane:%[0-9]+]]:fpr128 = INSvi32lane [[COPY1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi32lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(s32) = COPY $s0 - %1:fpr(<4 x s32>) = COPY $q1 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %1, %0(s32), %3(s64) - $q0 = COPY %2(<4 x s32>) + %0:fpr(i32) = COPY $s0 + %1:fpr(<4 x i32>) = COPY $q1 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<4 x i32>) = G_INSERT_VECTOR_ELT %1, %0(i32), %3(i64) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -191,11 +191,11 @@ body: | ; CHECK-NEXT: [[INSvi32gpr:%[0-9]+]]:fpr128 = INSvi32gpr [[COPY1]], 1, [[COPY]] ; CHECK-NEXT: $q0 = COPY [[INSvi32gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s32) = COPY $w0 - %1:fpr(<4 x s32>) = COPY $q0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %1, %0(s32), %3(s64) - $q0 = COPY %2(<4 x s32>) + %0:gpr(i32) = COPY $w0 + %1:fpr(<4 x i32>) = COPY $q0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<4 x i32>) = G_INSERT_VECTOR_ELT %1, %0(i32), %3(i64) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -220,13 +220,13 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi16gpr]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s16) = G_TRUNC %0 - %1:fpr(<4 x s16>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %4:gpr(s32) = G_ANYEXT %trunc - %2:fpr(<4 x s16>) = G_INSERT_VECTOR_ELT %1, %4(s32), %3(s64) - $d0 = COPY %2(<4 x s16>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i16) = G_TRUNC %0 + %1:fpr(<4 x i16>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %4:gpr(i32) = G_ANYEXT %trunc + %2:fpr(<4 x i16>) = G_INSERT_VECTOR_ELT %1, %4(i32), %3(i64) + $d0 = COPY %2(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -250,11 +250,11 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[COPY1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(s64) = COPY $d0 - %1:fpr(<2 x s64>) = COPY $q1 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %1, %0(s64), %3(s64) - $q0 = COPY %2(<2 x s64>) + %0:fpr(i64) = COPY $d0 + %1:fpr(<2 x i64>) = COPY $q1 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<2 x i64>) = G_INSERT_VECTOR_ELT %1, %0(i64), %3(i64) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -276,11 +276,11 @@ body: | ; CHECK-NEXT: [[INSvi64gpr:%[0-9]+]]:fpr128 = INSvi64gpr [[COPY1]], 0, [[COPY]] ; CHECK-NEXT: $q0 = COPY [[INSvi64gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s64) = COPY $x0 - %1:fpr(<2 x s64>) = COPY $q0 - %3:gpr(s64) = G_CONSTANT i64 0 - %2:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %1, %0(s64), %3(s64) - $q0 = COPY %2(<2 x s64>) + %0:gpr(i64) = COPY $x0 + %1:fpr(<2 x i64>) = COPY $q0 + %3:gpr(i64) = G_CONSTANT i64 0 + %2:fpr(<2 x i64>) = G_INSERT_VECTOR_ELT %1, %0(i64), %3(i64) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -307,11 +307,11 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi32lane]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(s32) = COPY $s0 - %1:fpr(<2 x s32>) = COPY $d1 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<2 x s32>) = G_INSERT_VECTOR_ELT %1, %0(s32), %3(s64) - $d0 = COPY %2(<2 x s32>) + %0:fpr(i32) = COPY $s0 + %1:fpr(<2 x i32>) = COPY $d1 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<2 x i32>) = G_INSERT_VECTOR_ELT %1, %0(i32), %3(i64) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -336,11 +336,11 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi32gpr]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:gpr(s32) = COPY $w0 - %1:fpr(<2 x s32>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<2 x s32>) = G_INSERT_VECTOR_ELT %1, %0(s32), %3(s64) - $d0 = COPY %2(<2 x s32>) + %0:gpr(i32) = COPY $w0 + %1:fpr(<2 x i32>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<2 x i32>) = G_INSERT_VECTOR_ELT %1, %0(i32), %3(i64) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-int-ptr-casts.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-int-ptr-casts.mir index e50f0fd21e7a9..ac5575b88fc31 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-int-ptr-casts.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-int-ptr-casts.mir @@ -30,7 +30,7 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY $x0 ; CHECK-NEXT: $x0 = COPY [[COPY]] - %0(s64) = COPY $x0 + %0(i64) = COPY $x0 %1(p0) = G_INTTOPTR %0 $x0 = COPY %1(p0) ... @@ -52,8 +52,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 ; CHECK-NEXT: $x0 = COPY [[COPY]] %0(p0) = COPY $x0 - %1(s64) = G_PTRTOINT %0 - $x0 = COPY %1(s64) + %1(i64) = G_PTRTOINT %0 + $x0 = COPY %1(i64) ... --- @@ -104,8 +104,8 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $h0 %ptr:gpr(p0) = COPY $x0 %ptr2int:gpr(i64) = G_PTRTOINT %ptr(p0) - %int:gpr(s16) = G_TRUNC %ptr2int(i64) - $h0 = COPY %int(s16) + %int:gpr(i16) = G_TRUNC %ptr2int(i64) + $h0 = COPY %int(i16) RET_ReallyLR implicit $h0 ... @@ -131,8 +131,8 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $b0 %ptr:gpr(p0) = COPY $x0 %ptr2int:gpr(i64) = G_PTRTOINT %ptr(p0) - %int:gpr(s8) = G_TRUNC %ptr2int(i64) - $b0 = COPY %int(s8) + %int:gpr(i8) = G_TRUNC %ptr2int(i64) + $b0 = COPY %int(i8) RET_ReallyLR implicit $b0 ... @@ -179,10 +179,10 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[COPY]].dsub ; CHECK-NEXT: $x0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %1:fpr(<2 x s64>) = COPY $q0 - %2:fpr(<2 x p0>) = G_INTTOPTR %1(<2 x s64>) - %4:gpr(s64) = G_CONSTANT i64 0 - %3:fpr(p0) = G_EXTRACT_VECTOR_ELT %2(<2 x p0>), %4(s64) + %1:fpr(<2 x i64>) = COPY $q0 + %2:fpr(<2 x p0>) = G_INTTOPTR %1(<2 x i64>) + %4:gpr(i64) = G_CONSTANT i64 0 + %3:fpr(p0) = G_EXTRACT_VECTOR_ELT %2(<2 x p0>), %4(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $x0 ... @@ -202,7 +202,7 @@ body: | ; CHECK-NEXT: $q0 = COPY %ptr ; CHECK-NEXT: RET_ReallyLR implicit $q0 %ptr:fpr(<2 x p0>) = COPY $q0 - %int:fpr(<2 x s64>) = G_PTRTOINT %ptr(<2 x p0>) - $q0 = COPY %int(<2 x s64>) + %int:fpr(<2 x i64>) = G_PTRTOINT %ptr(<2 x p0>) + $q0 = COPY %int(<2 x i64>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-aarch64-hint.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-aarch64-hint.mir index c63f99218f05c..cc904bca9bf88 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-aarch64-hint.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-aarch64-hint.mir @@ -24,6 +24,6 @@ body: | bb.0: liveins: $w0 - %0(s32) = G_CONSTANT i32 1 + %0(i32) = G_CONSTANT i32 1 G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.hint), %0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-crypto-aesmc.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-crypto-aesmc.mir index 7d17336ad7543..06aa66678f071 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-crypto-aesmc.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-crypto-aesmc.mir @@ -20,9 +20,9 @@ body: | ; CHECK-NEXT: [[AESErr:%[0-9]+]]:fpr128 = AESErr [[COPY]], [[COPY1]] ; CHECK-NEXT: [[AESMCrrTied:%[0-9]+]]:fpr128 = AESMCrrTied [[AESErr]] ; CHECK-NEXT: $q0 = COPY [[AESMCrrTied]] - %0:fpr(<16 x s8>) = COPY $q0 - %1:fpr(<16 x s8>) = COPY $q1 - %2:fpr(<16 x s8>) = G_INTRINSIC intrinsic(@llvm.aarch64.crypto.aese), %0, %1 - %3:fpr(<16 x s8>) = G_INTRINSIC intrinsic(@llvm.aarch64.crypto.aesmc), %2 - $q0 = COPY %3(<16 x s8>) + %0:fpr(<16 x i8>) = COPY $q0 + %1:fpr(<16 x i8>) = COPY $q1 + %2:fpr(<16 x i8>) = G_INTRINSIC intrinsic(@llvm.aarch64.crypto.aese), %0, %1 + %3:fpr(<16 x i8>) = G_INTRINSIC intrinsic(@llvm.aarch64.crypto.aesmc), %2 + $q0 = COPY %3(<16 x i8>) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir index 92121b0b42162..0bd939e217e54 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir @@ -25,7 +25,7 @@ body: | ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64common = IMPLICIT_DEF - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[DEF]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[DEF]], 0 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64common = SUBREG_TO_REG [[LDRBBui]], %subreg.sub_32 ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[SUBREG_TO_REG]], 8, 0, implicit-def $nzcv ; CHECK-NEXT: Bcc 8, %bb.3, implicit $nzcv @@ -47,16 +47,16 @@ body: | ; CHECK-NEXT: RET_ReallyLR bb.1: %1:gpr(p0) = G_IMPLICIT_DEF - %5:gpr(s64) = G_ZEXTLOAD %1(p0) :: (load (s8)) - %7:gpr(s64) = G_CONSTANT i64 8 - %16:gpr(s32) = G_ICMP intpred(ugt), %5(s64), %7 + %5:gpr(i64) = G_ZEXTLOAD %1(p0) :: (load (i8)) + %7:gpr(i64) = G_CONSTANT i64 8 + %16:gpr(i32) = G_ICMP intpred(ugt), %5(i64), %7 G_BRCOND %16, %bb.4 bb.2: successors: %bb.3, %bb.4 %9:gpr(p0) = G_JUMP_TABLE %jump-table.0 - G_BRJT %9(p0), %jump-table.0, %5(s64) + G_BRJT %9(p0), %jump-table.0, %5(i64) bb.3: G_BR %bb.4 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ld2.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ld2.mir index 933dcb9628314..7d4b72d428fdf 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ld2.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ld2.mir @@ -13,16 +13,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov8b:%[0-9]+]]:dd = LD2Twov8b %ptr :: (load (<8 x s64>)) + ; CHECK-NEXT: [[LD2Twov8b:%[0-9]+]]:dd = LD2Twov8b %ptr :: (load (<8 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD2Twov8b]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD2Twov8b]].dsub1 ; CHECK-NEXT: $d0 = COPY %dst1 ; CHECK-NEXT: $d1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<8 x s8>), %dst2:fpr(<8 x s8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<8 x s64>)) - $d0 = COPY %dst1(<8 x s8>) - $d1 = COPY %dst2(<8 x s8>) + %dst1:fpr(<8 x i8>), %dst2:fpr(<8 x i8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<8 x i64>)) + $d0 = COPY %dst1(<8 x i8>) + $d1 = COPY %dst2(<8 x i8>) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -37,16 +37,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov16b:%[0-9]+]]:qq = LD2Twov16b %ptr :: (load (<16 x s64>)) + ; CHECK-NEXT: [[LD2Twov16b:%[0-9]+]]:qq = LD2Twov16b %ptr :: (load (<16 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD2Twov16b]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD2Twov16b]].qsub1 ; CHECK-NEXT: $q0 = COPY %dst1 ; CHECK-NEXT: $q1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<16 x s8>), %dst2:fpr(<16 x s8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<16 x s64>)) - $q0 = COPY %dst1(<16 x s8>) - $q1 = COPY %dst2(<16 x s8>) + %dst1:fpr(<16 x i8>), %dst2:fpr(<16 x i8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<16 x i64>)) + $q0 = COPY %dst1(<16 x i8>) + $q1 = COPY %dst2(<16 x i8>) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -61,16 +61,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov4h:%[0-9]+]]:dd = LD2Twov4h %ptr :: (load (<4 x s64>)) + ; CHECK-NEXT: [[LD2Twov4h:%[0-9]+]]:dd = LD2Twov4h %ptr :: (load (<4 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD2Twov4h]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD2Twov4h]].dsub1 ; CHECK-NEXT: $d0 = COPY %dst1 ; CHECK-NEXT: $d1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<4 x s16>), %dst2:fpr(<4 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<4 x s64>)) - $d0 = COPY %dst1(<4 x s16>) - $d1 = COPY %dst2(<4 x s16>) + %dst1:fpr(<4 x i16>), %dst2:fpr(<4 x i16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<4 x i64>)) + $d0 = COPY %dst1(<4 x i16>) + $d1 = COPY %dst2(<4 x i16>) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -85,16 +85,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov8h:%[0-9]+]]:qq = LD2Twov8h %ptr :: (load (<8 x s64>)) + ; CHECK-NEXT: [[LD2Twov8h:%[0-9]+]]:qq = LD2Twov8h %ptr :: (load (<8 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD2Twov8h]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD2Twov8h]].qsub1 ; CHECK-NEXT: $q0 = COPY %dst1 ; CHECK-NEXT: $q1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<8 x s16>), %dst2:fpr(<8 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<8 x s64>)) - $q0 = COPY %dst1(<8 x s16>) - $q1 = COPY %dst2(<8 x s16>) + %dst1:fpr(<8 x i16>), %dst2:fpr(<8 x i16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<8 x i64>)) + $q0 = COPY %dst1(<8 x i16>) + $q1 = COPY %dst2(<8 x i16>) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -109,16 +109,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov2s:%[0-9]+]]:dd = LD2Twov2s %ptr :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LD2Twov2s:%[0-9]+]]:dd = LD2Twov2s %ptr :: (load (<2 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD2Twov2s]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD2Twov2s]].dsub1 ; CHECK-NEXT: $d0 = COPY %dst1 ; CHECK-NEXT: $d1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<2 x s32>), %dst2:fpr(<2 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<2 x s64>)) - $d0 = COPY %dst1(<2 x s32>) - $d1 = COPY %dst2(<2 x s32>) + %dst1:fpr(<2 x i32>), %dst2:fpr(<2 x i32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<2 x i64>)) + $d0 = COPY %dst1(<2 x i32>) + $d1 = COPY %dst2(<2 x i32>) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -133,16 +133,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov4s:%[0-9]+]]:qq = LD2Twov4s %ptr :: (load (<4 x s64>)) + ; CHECK-NEXT: [[LD2Twov4s:%[0-9]+]]:qq = LD2Twov4s %ptr :: (load (<4 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD2Twov4s]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD2Twov4s]].qsub1 ; CHECK-NEXT: $q0 = COPY %dst1 ; CHECK-NEXT: $q1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<4 x s32>), %dst2:fpr(<4 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<4 x s64>)) - $q0 = COPY %dst1(<4 x s32>) - $q1 = COPY %dst2(<4 x s32>) + %dst1:fpr(<4 x i32>), %dst2:fpr(<4 x i32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<4 x i64>)) + $q0 = COPY %dst1(<4 x i32>) + $q1 = COPY %dst2(<4 x i32>) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -157,16 +157,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov2d:%[0-9]+]]:qq = LD2Twov2d %ptr :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LD2Twov2d:%[0-9]+]]:qq = LD2Twov2d %ptr :: (load (<2 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD2Twov2d]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD2Twov2d]].qsub1 ; CHECK-NEXT: $q0 = COPY %dst1 ; CHECK-NEXT: $q1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<2 x s64>), %dst2:fpr(<2 x s64>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<2 x s64>)) - $q0 = COPY %dst1(<2 x s64>) - $q1 = COPY %dst2(<2 x s64>) + %dst1:fpr(<2 x i64>), %dst2:fpr(<2 x i64>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<2 x i64>)) + $q0 = COPY %dst1(<2 x i64>) + $q1 = COPY %dst2(<2 x i64>) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -205,16 +205,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD1Twov1d:%[0-9]+]]:dd = LD1Twov1d %ptr :: (load (s64)) + ; CHECK-NEXT: [[LD1Twov1d:%[0-9]+]]:dd = LD1Twov1d %ptr :: (load (i64)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD1Twov1d]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD1Twov1d]].dsub1 ; CHECK-NEXT: $d0 = COPY %dst1 ; CHECK-NEXT: $d1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(s64), %dst2:fpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (s64)) - $d0 = COPY %dst1(s64) - $d1 = COPY %dst2(s64) + %dst1:fpr(i64), %dst2:fpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (i64)) + $d0 = COPY %dst1(i64) + $d1 = COPY %dst2(i64) RET_ReallyLR implicit $d0, implicit $d1 ... --- diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ld4.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ld4.mir index 03e271e15e991..cd15b7b4b0e2d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ld4.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ld4.mir @@ -13,7 +13,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv8b:%[0-9]+]]:dddd = LD4Fourv8b %ptr :: (load (<8 x s64>)) + ; CHECK-NEXT: [[LD4Fourv8b:%[0-9]+]]:dddd = LD4Fourv8b %ptr :: (load (<8 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD4Fourv8b]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD4Fourv8b]].dsub1 ; CHECK-NEXT: %dst3:fpr64 = COPY [[LD4Fourv8b]].dsub2 @@ -24,11 +24,11 @@ body: | ; CHECK-NEXT: $d3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<8 x s8>), %dst2:fpr(<8 x s8>), %dst3:fpr(<8 x s8>), %dst4:fpr(<8 x s8>)= G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<8 x s64>)) - $d0 = COPY %dst1(<8 x s8>) - $d1 = COPY %dst2(<8 x s8>) - $d2 = COPY %dst3(<8 x s8>) - $d3 = COPY %dst4(<8 x s8>) + %dst1:fpr(<8 x i8>), %dst2:fpr(<8 x i8>), %dst3:fpr(<8 x i8>), %dst4:fpr(<8 x i8>)= G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<8 x i64>)) + $d0 = COPY %dst1(<8 x i8>) + $d1 = COPY %dst2(<8 x i8>) + $d2 = COPY %dst3(<8 x i8>) + $d3 = COPY %dst4(<8 x i8>) RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 ... --- @@ -43,7 +43,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv16b:%[0-9]+]]:qqqq = LD4Fourv16b %ptr :: (load (<16 x s64>)) + ; CHECK-NEXT: [[LD4Fourv16b:%[0-9]+]]:qqqq = LD4Fourv16b %ptr :: (load (<16 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD4Fourv16b]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD4Fourv16b]].qsub1 ; CHECK-NEXT: %dst3:fpr128 = COPY [[LD4Fourv16b]].qsub2 @@ -54,11 +54,11 @@ body: | ; CHECK-NEXT: $q3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<16 x s8>), %dst2:fpr(<16 x s8>), %dst3:fpr(<16 x s8>), %dst4:fpr(<16 x s8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<16 x s64>)) - $q0 = COPY %dst1(<16 x s8>) - $q1 = COPY %dst2(<16 x s8>) - $q2 = COPY %dst3(<16 x s8>) - $q3 = COPY %dst4(<16 x s8>) + %dst1:fpr(<16 x i8>), %dst2:fpr(<16 x i8>), %dst3:fpr(<16 x i8>), %dst4:fpr(<16 x i8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<16 x i64>)) + $q0 = COPY %dst1(<16 x i8>) + $q1 = COPY %dst2(<16 x i8>) + $q2 = COPY %dst3(<16 x i8>) + $q3 = COPY %dst4(<16 x i8>) RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 ... --- @@ -73,7 +73,7 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv4h:%[0-9]+]]:dddd = LD4Fourv4h %ptr :: (load (<4 x s64>)) + ; CHECK-NEXT: [[LD4Fourv4h:%[0-9]+]]:dddd = LD4Fourv4h %ptr :: (load (<4 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD4Fourv4h]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD4Fourv4h]].dsub1 ; CHECK-NEXT: %dst3:fpr64 = COPY [[LD4Fourv4h]].dsub2 @@ -84,11 +84,11 @@ body: | ; CHECK-NEXT: $d3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<4 x s16>), %dst2:fpr(<4 x s16>), %dst3:fpr(<4 x s16>), %dst4:fpr(<4 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<4 x s64>)) - $d0 = COPY %dst1(<4 x s16>) - $d1 = COPY %dst2(<4 x s16>) - $d2 = COPY %dst3(<4 x s16>) - $d3 = COPY %dst4(<4 x s16>) + %dst1:fpr(<4 x i16>), %dst2:fpr(<4 x i16>), %dst3:fpr(<4 x i16>), %dst4:fpr(<4 x i16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<4 x i64>)) + $d0 = COPY %dst1(<4 x i16>) + $d1 = COPY %dst2(<4 x i16>) + $d2 = COPY %dst3(<4 x i16>) + $d3 = COPY %dst4(<4 x i16>) RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 ... --- @@ -103,7 +103,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv8h:%[0-9]+]]:qqqq = LD4Fourv8h %ptr :: (load (<8 x s64>)) + ; CHECK-NEXT: [[LD4Fourv8h:%[0-9]+]]:qqqq = LD4Fourv8h %ptr :: (load (<8 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD4Fourv8h]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD4Fourv8h]].qsub1 ; CHECK-NEXT: %dst3:fpr128 = COPY [[LD4Fourv8h]].qsub2 @@ -114,11 +114,11 @@ body: | ; CHECK-NEXT: $q3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<8 x s16>), %dst2:fpr(<8 x s16>), %dst3:fpr(<8 x s16>), %dst4:fpr(<8 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<8 x s64>)) - $q0 = COPY %dst1(<8 x s16>) - $q1 = COPY %dst2(<8 x s16>) - $q2 = COPY %dst3(<8 x s16>) - $q3 = COPY %dst4(<8 x s16>) + %dst1:fpr(<8 x i16>), %dst2:fpr(<8 x i16>), %dst3:fpr(<8 x i16>), %dst4:fpr(<8 x i16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<8 x i64>)) + $q0 = COPY %dst1(<8 x i16>) + $q1 = COPY %dst2(<8 x i16>) + $q2 = COPY %dst3(<8 x i16>) + $q3 = COPY %dst4(<8 x i16>) RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 ... --- @@ -133,7 +133,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv2s:%[0-9]+]]:dddd = LD4Fourv2s %ptr :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LD4Fourv2s:%[0-9]+]]:dddd = LD4Fourv2s %ptr :: (load (<2 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD4Fourv2s]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD4Fourv2s]].dsub1 ; CHECK-NEXT: %dst3:fpr64 = COPY [[LD4Fourv2s]].dsub2 @@ -144,11 +144,11 @@ body: | ; CHECK-NEXT: $d3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<2 x s32>), %dst2:fpr(<2 x s32>), %dst3:fpr(<2 x s32>), %dst4:fpr(<2 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<2 x s64>)) - $d0 = COPY %dst1(<2 x s32>) - $d1 = COPY %dst2(<2 x s32>) - $d2 = COPY %dst3(<2 x s32>) - $d3 = COPY %dst4(<2 x s32>) + %dst1:fpr(<2 x i32>), %dst2:fpr(<2 x i32>), %dst3:fpr(<2 x i32>), %dst4:fpr(<2 x i32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<2 x i64>)) + $d0 = COPY %dst1(<2 x i32>) + $d1 = COPY %dst2(<2 x i32>) + $d2 = COPY %dst3(<2 x i32>) + $d3 = COPY %dst4(<2 x i32>) RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 ... --- @@ -163,7 +163,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv4s:%[0-9]+]]:qqqq = LD4Fourv4s %ptr :: (load (<4 x s64>)) + ; CHECK-NEXT: [[LD4Fourv4s:%[0-9]+]]:qqqq = LD4Fourv4s %ptr :: (load (<4 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD4Fourv4s]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD4Fourv4s]].qsub1 ; CHECK-NEXT: %dst3:fpr128 = COPY [[LD4Fourv4s]].qsub2 @@ -174,11 +174,11 @@ body: | ; CHECK-NEXT: $q3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<4 x s32>), %dst2:fpr(<4 x s32>), %dst3:fpr(<4 x s32>), %dst4:fpr(<4 x s32>)= G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<4 x s64>)) - $q0 = COPY %dst1(<4 x s32>) - $q1 = COPY %dst2(<4 x s32>) - $q2 = COPY %dst3(<4 x s32>) - $q3 = COPY %dst4(<4 x s32>) + %dst1:fpr(<4 x i32>), %dst2:fpr(<4 x i32>), %dst3:fpr(<4 x i32>), %dst4:fpr(<4 x i32>)= G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<4 x i64>)) + $q0 = COPY %dst1(<4 x i32>) + $q1 = COPY %dst2(<4 x i32>) + $q2 = COPY %dst3(<4 x i32>) + $q3 = COPY %dst4(<4 x i32>) RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 ... --- @@ -193,7 +193,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv2d:%[0-9]+]]:qqqq = LD4Fourv2d %ptr :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LD4Fourv2d:%[0-9]+]]:qqqq = LD4Fourv2d %ptr :: (load (<2 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD4Fourv2d]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD4Fourv2d]].qsub1 ; CHECK-NEXT: %dst3:fpr128 = COPY [[LD4Fourv2d]].qsub2 @@ -204,11 +204,11 @@ body: | ; CHECK-NEXT: $q3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<2 x s64>), %dst2:fpr(<2 x s64>), %dst3:fpr(<2 x s64>), %dst4:fpr(<2 x s64>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<2 x s64>)) - $q0 = COPY %dst1(<2 x s64>) - $q1 = COPY %dst2(<2 x s64>) - $q2 = COPY %dst3(<2 x s64>) - $q3 = COPY %dst4(<2 x s64>) + %dst1:fpr(<2 x i64>), %dst2:fpr(<2 x i64>), %dst3:fpr(<2 x i64>), %dst4:fpr(<2 x i64>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<2 x i64>)) + $q0 = COPY %dst1(<2 x i64>) + $q1 = COPY %dst2(<2 x i64>) + $q2 = COPY %dst3(<2 x i64>) + $q3 = COPY %dst4(<2 x i64>) RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 ... --- @@ -253,7 +253,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD1Fourv1d:%[0-9]+]]:dddd = LD1Fourv1d %ptr :: (load (s64)) + ; CHECK-NEXT: [[LD1Fourv1d:%[0-9]+]]:dddd = LD1Fourv1d %ptr :: (load (i64)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD1Fourv1d]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD1Fourv1d]].dsub1 ; CHECK-NEXT: %dst3:fpr64 = COPY [[LD1Fourv1d]].dsub2 @@ -264,11 +264,11 @@ body: | ; CHECK-NEXT: $d3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(s64), %dst2:fpr(s64), %dst3:fpr(s64), %dst4:fpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (s64)) - $d0 = COPY %dst1(s64) - $d1 = COPY %dst2(s64) - $d2 = COPY %dst3(s64) - $d3 = COPY %dst4(s64) + %dst1:fpr(i64), %dst2:fpr(i64), %dst3:fpr(i64), %dst4:fpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (i64)) + $d0 = COPY %dst1(i64) + $d1 = COPY %dst2(i64) + $d2 = COPY %dst3(i64) + $d3 = COPY %dst4(i64) RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 ... --- diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ldaxr-intrin.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ldaxr-intrin.mir index 6526cd977eb55..e86536563ae9e 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ldaxr-intrin.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ldaxr-intrin.mir @@ -21,12 +21,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDAXRB:%[0-9]+]]:gpr32 = LDAXRB [[COPY]] :: (volatile load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDAXRB:%[0-9]+]]:gpr32 = LDAXRB [[COPY]] :: (volatile load (i8) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDAXRB]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (s8) from %ir.addr) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (i8) from %ir.addr) $x1 = COPY %1 RET_ReallyLR implicit $x1 @@ -44,12 +44,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDAXRH:%[0-9]+]]:gpr32 = LDAXRH [[COPY]] :: (volatile load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDAXRH:%[0-9]+]]:gpr32 = LDAXRH [[COPY]] :: (volatile load (i16) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDAXRH]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (s16) from %ir.addr) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (i16) from %ir.addr) $x1 = COPY %1 RET_ReallyLR implicit $x1 @@ -67,12 +67,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDAXRW:%[0-9]+]]:gpr32 = LDAXRW [[COPY]] :: (volatile load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDAXRW:%[0-9]+]]:gpr32 = LDAXRW [[COPY]] :: (volatile load (i32) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDAXRW]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (s32) from %ir.addr) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (i32) from %ir.addr) $x1 = COPY %1 RET_ReallyLR implicit $x1 @@ -90,10 +90,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDAXRX:%[0-9]+]]:gpr64 = LDAXRX [[COPY]] :: (volatile load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDAXRX:%[0-9]+]]:gpr64 = LDAXRX [[COPY]] :: (volatile load (i64) from %ir.addr) ; CHECK-NEXT: $x1 = COPY [[LDAXRX]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (s64) from %ir.addr) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (i64) from %ir.addr) $x1 = COPY %1 RET_ReallyLR implicit $x1 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ldxr-intrin.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ldxr-intrin.mir index 1eaafd517d986..5a654b3cfffc5 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ldxr-intrin.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ldxr-intrin.mir @@ -20,13 +20,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDXRB:%[0-9]+]]:gpr32 = LDXRB [[COPY]] :: (volatile load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDXRB:%[0-9]+]]:gpr32 = LDXRB [[COPY]] :: (volatile load (i8) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDXRB]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (s8) from %ir.addr) - $x1 = COPY %1(s64) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (i8) from %ir.addr) + $x1 = COPY %1(i64) RET_ReallyLR implicit $x1 ... @@ -43,13 +43,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDXRH:%[0-9]+]]:gpr32 = LDXRH [[COPY]] :: (volatile load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDXRH:%[0-9]+]]:gpr32 = LDXRH [[COPY]] :: (volatile load (i16) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDXRH]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (s16) from %ir.addr) - $x1 = COPY %1(s64) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (i16) from %ir.addr) + $x1 = COPY %1(i64) RET_ReallyLR implicit $x1 ... @@ -66,13 +66,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDXRW:%[0-9]+]]:gpr32 = LDXRW [[COPY]] :: (volatile load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDXRW:%[0-9]+]]:gpr32 = LDXRW [[COPY]] :: (volatile load (i32) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDXRW]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (s32) from %ir.addr) - $x1 = COPY %1(s64) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (i32) from %ir.addr) + $x1 = COPY %1(i64) RET_ReallyLR implicit $x1 @@ -90,10 +90,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDXRX:%[0-9]+]]:gpr64 = LDXRX [[COPY]] :: (volatile load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDXRX:%[0-9]+]]:gpr64 = LDXRX [[COPY]] :: (volatile load (i64) from %ir.addr) ; CHECK-NEXT: $x1 = COPY [[LDXRX]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (s64) from %ir.addr) - $x1 = COPY %1(s64) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (i64) from %ir.addr) + $x1 = COPY %1(i64) RET_ReallyLR implicit $x1 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-load-store-vector-of-ptr.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-load-store-vector-of-ptr.mir index b5e204433c4ad..d9712da595d23 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-load-store-vector-of-ptr.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-load-store-vector-of-ptr.mir @@ -35,12 +35,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<2 x s64>) into %ir.ptr) + ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<2 x i64>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR %0:fpr(<2 x p0>) = COPY $q0 %1:gpr(p0) = COPY $x0 - %2:fpr(<2 x s64>) = G_BITCAST %0(<2 x p0>) - G_STORE %2(<2 x s64>), %1(p0) :: (store (<2 x s64>) into %ir.ptr) + %2:fpr(<2 x i64>) = G_BITCAST %0(<2 x p0>) + G_STORE %2(<2 x i64>), %1(p0) :: (store (<2 x i64>) into %ir.ptr) RET_ReallyLR ... @@ -63,12 +63,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x s64>) from %ir.ptr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x i64>) from %ir.ptr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $x0 - %2:fpr(<2 x s64>) = G_LOAD %0(p0) :: (load (<2 x s64>) from %ir.ptr) - %1:fpr(<2 x p0>) = G_BITCAST %2(<2 x s64>) + %2:fpr(<2 x i64>) = G_LOAD %0(p0) :: (load (<2 x i64>) from %ir.ptr) + %1:fpr(<2 x p0>) = G_BITCAST %2(<2 x i64>) $q0 = COPY %1(<2 x p0>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-load.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-load.mir index bc094e7703b97..09db59db840ef 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-load.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-load.mir @@ -62,11 +62,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[COPY]], 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[COPY]], 0 :: (load (i64) from %ir.addr) ; CHECK-NEXT: $x0 = COPY [[LDRXui]] %0(p0) = COPY $x0 - %1(s64) = G_LOAD %0 :: (load (s64) from %ir.addr) - $x0 = COPY %1(s64) + %1(i64) = G_LOAD %0 :: (load (i64) from %ir.addr) + $x0 = COPY %1(i64) ... --- @@ -86,11 +86,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRWui]] %0(p0) = COPY $x0 - %1(s32) = G_LOAD %0 :: (load (s32) from %ir.addr) - $w0 = COPY %1(s32) + %1(i32) = G_LOAD %0 :: (load (i32) from %ir.addr) + $w0 = COPY %1(i32) ... --- @@ -106,11 +106,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_LOAD %0 :: (load (s16) from %ir.addr) - $w0 = COPY %1(s32) + %1:gpr(i32) = G_LOAD %0 :: (load (i16) from %ir.addr) + $w0 = COPY %1(i32) ... --- @@ -130,13 +130,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0(p0) = COPY $x0 - %1(s16) = G_LOAD %0 :: (load (s16) from %ir.addr) - %2:gpr(s32) = G_ANYEXT %1 - $w0 = COPY %2(s32) + %1(i16) = G_LOAD %0 :: (load (i16) from %ir.addr) + %2:gpr(i32) = G_ANYEXT %1 + $w0 = COPY %2(i32) ... --- @@ -152,11 +152,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRBBui]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_LOAD %0 :: (load (s8) from %ir.addr) - $w0 = COPY %1(s32) + %1:gpr(i32) = G_LOAD %0 :: (load (i8) from %ir.addr) + $w0 = COPY %1(i32) ... --- @@ -176,13 +176,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRBBui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0(p0) = COPY $x0 - %1(s8) = G_LOAD %0 :: (load (s8) from %ir.addr) - %2:gpr(s32) = G_ANYEXT %1 - $w0 = COPY %2(s32) + %1(i8) = G_LOAD %0 :: (load (i8) from %ir.addr) + %2:gpr(i32) = G_ANYEXT %1 + $w0 = COPY %2(i32) ... --- @@ -204,11 +204,11 @@ body: | ; CHECK-LABEL: name: load_fi_s64_gpr ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui %stack.0.ptr0, 0 :: (load (s64)) + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui %stack.0.ptr0, 0 :: (load (i64)) ; CHECK-NEXT: $x0 = COPY [[LDRXui]] %0(p0) = G_FRAME_INDEX %stack.0.ptr0 - %1(s64) = G_LOAD %0 :: (load (s64)) - $x0 = COPY %1(s64) + %1(i64) = G_LOAD %0 :: (load (i64)) + $x0 = COPY %1(i64) ... --- @@ -230,12 +230,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[COPY]], 16 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[COPY]], 16 :: (load (i64) from %ir.addr) ; CHECK-NEXT: $x0 = COPY [[LDRXui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 128 + %1(i64) = G_CONSTANT i64 128 %2(p0) = G_PTR_ADD %0, %1 - %3(s64) = G_LOAD %2 :: (load (s64) from %ir.addr) + %3(i64) = G_LOAD %2 :: (load (i64) from %ir.addr) $x0 = COPY %3 ... @@ -258,12 +258,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 128 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 128 :: (load (i32) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRWui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 512 + %1(i64) = G_CONSTANT i64 512 %2(p0) = G_PTR_ADD %0, %1 - %3(s32) = G_LOAD %2 :: (load (s32) from %ir.addr) + %3(i32) = G_LOAD %2 :: (load (i32) from %ir.addr) $w0 = COPY %3 ... @@ -286,14 +286,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 32 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 32 :: (load (i16) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 64 + %1(i64) = G_CONSTANT i64 64 %2(p0) = G_PTR_ADD %0, %1 - %3(s16) = G_LOAD %2 :: (load (s16) from %ir.addr) - %4:gpr(s32) = G_ANYEXT %3 + %3(i16) = G_LOAD %2 :: (load (i16) from %ir.addr) + %4:gpr(i32) = G_ANYEXT %3 $w0 = COPY %4 ... @@ -316,14 +316,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 1 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 1 :: (load (i8) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRBBui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 1 + %1(i64) = G_CONSTANT i64 1 %2(p0) = G_PTR_ADD %0, %1 - %3(s8) = G_LOAD %2 :: (load (s8) from %ir.addr) - %4:gpr(s32) = G_ANYEXT %3 + %3(i8) = G_LOAD %2 :: (load (i8) from %ir.addr) + %4:gpr(i32) = G_ANYEXT %3 $w0 = COPY %4 ... @@ -344,11 +344,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (i64) from %ir.addr) ; CHECK-NEXT: $d0 = COPY [[LDRDui]] %0(p0) = COPY $x0 - %1(s64) = G_LOAD %0 :: (load (s64) from %ir.addr) - $d0 = COPY %1(s64) + %1(i64) = G_LOAD %0 :: (load (i64) from %ir.addr) + $d0 = COPY %1(i64) ... --- @@ -368,11 +368,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY]], 0 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY]], 0 :: (load (i32) from %ir.addr) ; CHECK-NEXT: $s0 = COPY [[LDRSui]] %0(p0) = COPY $x0 - %1(s32) = G_LOAD %0 :: (load (s32) from %ir.addr) - $s0 = COPY %1(s32) + %1(i32) = G_LOAD %0 :: (load (i32) from %ir.addr) + $s0 = COPY %1(i32) ... --- @@ -392,11 +392,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $h0 = COPY [[LDRHui]] %0(p0) = COPY $x0 - %1(s16) = G_LOAD %0 :: (load (s16) from %ir.addr) - $h0 = COPY %1(s16) + %1(i16) = G_LOAD %0 :: (load (i16) from %ir.addr) + $h0 = COPY %1(i16) ... --- @@ -416,11 +416,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (i8) from %ir.addr) ; CHECK-NEXT: $b0 = COPY [[LDRBui]] %0(p0) = COPY $x0 - %1(s8) = G_LOAD %0 :: (load (s8) from %ir.addr) - $b0 = COPY %1(s8) + %1(i8) = G_LOAD %0 :: (load (i8) from %ir.addr) + $b0 = COPY %1(i8) ... --- @@ -442,12 +442,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 1 :: (load (i64) from %ir.addr) ; CHECK-NEXT: $d0 = COPY [[LDRDui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 8 + %1(i64) = G_CONSTANT i64 8 %2(p0) = G_PTR_ADD %0, %1 - %3(s64) = G_LOAD %2 :: (load (s64) from %ir.addr) + %3(i64) = G_LOAD %2 :: (load (i64) from %ir.addr) $d0 = COPY %3 ... @@ -470,12 +470,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY]], 4 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY]], 4 :: (load (i32) from %ir.addr) ; CHECK-NEXT: $s0 = COPY [[LDRSui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 16 + %1(i64) = G_CONSTANT i64 16 %2(p0) = G_PTR_ADD %0, %1 - %3(s32) = G_LOAD %2 :: (load (s32) from %ir.addr) + %3(i32) = G_LOAD %2 :: (load (i32) from %ir.addr) $s0 = COPY %3 ... @@ -498,12 +498,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 32 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 32 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $h0 = COPY [[LDRHui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 64 + %1(i64) = G_CONSTANT i64 64 %2(p0) = G_PTR_ADD %0, %1 - %3(s16) = G_LOAD %2 :: (load (s16) from %ir.addr) + %3(i16) = G_LOAD %2 :: (load (i16) from %ir.addr) $h0 = COPY %3 ... @@ -526,12 +526,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 32 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 32 :: (load (i8) from %ir.addr) ; CHECK-NEXT: $b0 = COPY [[LDRBui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 32 + %1(i64) = G_CONSTANT i64 32 %2(p0) = G_PTR_ADD %0, %1 - %3(s8) = G_LOAD %2 :: (load (s8) from %ir.addr) + %3(i8) = G_LOAD %2 :: (load (i8) from %ir.addr) $b0 = COPY %3 ... --- @@ -551,11 +551,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<2 x s32>) from %ir.addr) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<2 x i32>) from %ir.addr) ; CHECK-NEXT: $d0 = COPY [[LDRDui]] %0(p0) = COPY $x0 - %1(<2 x s32>) = G_LOAD %0 :: (load (<2 x s32>) from %ir.addr) - $d0 = COPY %1(<2 x s32>) + %1(<2 x i32>) = G_LOAD %0 :: (load (<2 x i32>) from %ir.addr) + $d0 = COPY %1(<2 x i32>) ... --- name: load_v2s64 @@ -574,11 +574,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x s64>) from %ir.addr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x i64>) from %ir.addr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] %0(p0) = COPY $x0 - %1(<2 x s64>) = G_LOAD %0 :: (load (<2 x s64>) from %ir.addr) - $q0 = COPY %1(<2 x s64>) + %1(<2 x i64>) = G_LOAD %0 :: (load (<2 x i64>) from %ir.addr) + $q0 = COPY %1(<2 x i64>) ... --- name: load_4xi16 @@ -598,12 +598,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<4 x s16>) from %ir.ptr) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<4 x i16>) from %ir.ptr) ; CHECK-NEXT: $d0 = COPY [[LDRDui]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:fpr(<4 x s16>) = G_LOAD %0(p0) :: (load (<4 x s16>) from %ir.ptr) - $d0 = COPY %1(<4 x s16>) + %1:fpr(<4 x i16>) = G_LOAD %0(p0) :: (load (<4 x i16>) from %ir.ptr) + $d0 = COPY %1(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -625,12 +625,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x s32>) from %ir.ptr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x i32>) from %ir.ptr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $x0 - %1:fpr(<4 x s32>) = G_LOAD %0(p0) :: (load (<4 x s32>) from %ir.ptr) - $q0 = COPY %1(<4 x s32>) + %1:fpr(<4 x i32>) = G_LOAD %0(p0) :: (load (<4 x i32>) from %ir.ptr) + $q0 = COPY %1(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -652,12 +652,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<8 x s16>) from %ir.ptr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<8 x i16>) from %ir.ptr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $x0 - %1:fpr(<8 x s16>) = G_LOAD %0(p0) :: (load (<8 x s16>) from %ir.ptr) - $q0 = COPY %1(<8 x s16>) + %1:fpr(<8 x i16>) = G_LOAD %0(p0) :: (load (<8 x i16>) from %ir.ptr) + $q0 = COPY %1(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -679,12 +679,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<16 x s8>) from %ir.ptr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<16 x i8>) from %ir.ptr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $x0 - %1:fpr(<16 x s8>) = G_LOAD %0(p0) :: (load (<16 x s8>) from %ir.ptr) - $q0 = COPY %1(<16 x s8>) + %1:fpr(<16 x i8>) = G_LOAD %0(p0) :: (load (<16 x i8>) from %ir.ptr) + $q0 = COPY %1(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -710,15 +710,15 @@ body: | ; CHECK: liveins: $w3, $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[LDRHui]], %subreg.hsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %16:fpr(s32) = G_LOAD %0(p0) :: (load (s16)) - %24:gpr(s32) = COPY %16(s32) - $w0 = COPY %24(s32) + %16:fpr(i32) = G_LOAD %0(p0) :: (load (i16)) + %24:gpr(i32) = COPY %16(i32) + $w0 = COPY %24(i32) RET_ReallyLR ... @@ -744,15 +744,15 @@ body: | ; CHECK: liveins: $w3, $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[LDRBui]], %subreg.bsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %16:fpr(s32) = G_LOAD %0(p0) :: (load (s8)) - %24:gpr(s32) = COPY %16(s32) - $w0 = COPY %24(s32) + %16:fpr(i32) = G_LOAD %0(p0) :: (load (i8)) + %24:gpr(i32) = COPY %16(i32) + $w0 = COPY %24(i32) RET_ReallyLR ... @@ -770,16 +770,16 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD1i32_:%[0-9]+]]:fpr128 = LD1i32 [[COPY]], 0, [[COPY1]] :: (load (s32)) + ; CHECK-NEXT: [[LD1i32_:%[0-9]+]]:fpr128 = LD1i32 [[COPY]], 0, [[COPY1]] :: (load (i32)) ; CHECK-NEXT: $q0 = COPY [[LD1i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 + %0:fpr(<4 x i32>) = COPY $q0 %1:gpr(p0) = COPY $x0 - %2:fpr(s32) = G_LOAD %1(p0) :: (load (s32)) - %3:gpr(s32) = G_CONSTANT i32 3 - %5:gpr(s64) = G_CONSTANT i64 0 - %4:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %0, %2(s32), %5(s64) - $q0 = COPY %4(<4 x s32>) + %2:fpr(i32) = G_LOAD %1(p0) :: (load (i32)) + %3:gpr(i32) = G_CONSTANT i32 3 + %5:gpr(i64) = G_CONSTANT i64 0 + %4:fpr(<4 x i32>) = G_INSERT_VECTOR_ELT %0, %2(i32), %5(i64) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -798,21 +798,21 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY1]], 0 :: (load (s32)) + ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY1]], 0 :: (load (i32)) ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 3 - ; CHECK-NEXT: STRWui [[MOVi32imm]], [[COPY1]], 0 :: (store (s32)) + ; CHECK-NEXT: STRWui [[MOVi32imm]], [[COPY1]], 0 :: (store (i32)) ; CHECK-NEXT: [[DEF:%[0-9]+]]:fpr128 = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF]], [[LDRSui]], %subreg.ssub ; CHECK-NEXT: [[INSvi32lane:%[0-9]+]]:fpr128 = INSvi32lane [[COPY]], 0, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi32lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 + %0:fpr(<4 x i32>) = COPY $q0 %1:gpr(p0) = COPY $x0 - %2:fpr(s32) = G_LOAD %1(p0) :: (load (s32)) - %3:gpr(s32) = G_CONSTANT i32 3 - G_STORE %3(s32), %1(p0) :: (store (s32)) - %5:gpr(s64) = G_CONSTANT i64 0 - %4:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %0, %2(s32), %5(s64) - $q0 = COPY %4(<4 x s32>) + %2:fpr(i32) = G_LOAD %1(p0) :: (load (i32)) + %3:gpr(i32) = G_CONSTANT i32 3 + G_STORE %3(i32), %1(p0) :: (store (i32)) + %5:gpr(i64) = G_CONSTANT i64 0 + %4:fpr(<4 x i32>) = G_INSERT_VECTOR_ELT %0, %2(i32), %5(i64) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir index 604cb96e38dc3..186f2c94ecdca 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir @@ -27,21 +27,21 @@ body: | ; CHECK-NEXT: BL &modfl, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $q0, implicit $x0, implicit-def $q0 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr128 = COPY $q0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui %stack.0, 0 :: (load (s128) from %stack.0) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui %stack.0, 0 :: (load (i128) from %stack.0) ; CHECK-NEXT: $q0 = COPY [[COPY1]] ; CHECK-NEXT: $q1 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 - %0:fpr(s128) = COPY $q0 + %0:fpr(i128) = COPY $q0 %3:gpr(p0) = G_FRAME_INDEX %stack.0 ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp - $q0 = COPY %0(s128) + $q0 = COPY %0(i128) $x0 = COPY %3(p0) BL &modfl, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $q0, implicit $x0, implicit-def $q0 ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp - %1:fpr(s128) = COPY $q0 - %2:fpr(s128) = G_LOAD %3(p0) :: (load (s128) from %stack.0) - $q0 = COPY %1(s128) - $q1 = COPY %2(s128) + %1:fpr(i128) = COPY $q0 + %2:fpr(i128) = G_LOAD %3(p0) :: (load (i128) from %stack.0) + $q0 = COPY %1(i128) + $q1 = COPY %2(i128) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -72,21 +72,21 @@ body: | ; CHECK-NEXT: BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (s64) from %stack.0) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (i64) from %stack.0) ; CHECK-NEXT: $d0 = COPY [[COPY1]] ; CHECK-NEXT: $d1 = COPY [[LDRDui]] ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %3:gpr(p0) = G_FRAME_INDEX %stack.0 ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp - $d0 = COPY %0(s64) + $d0 = COPY %0(i64) $x0 = COPY %3(p0) BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0 ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp - %1:fpr(s64) = COPY $d0 - %2:fpr(s64) = G_LOAD %3(p0) :: (load (s64) from %stack.0) - $d0 = COPY %1(s64) - $d1 = COPY %2(s64) + %1:fpr(i64) = COPY $d0 + %2:fpr(i64) = G_LOAD %3(p0) :: (load (i64) from %stack.0) + $d0 = COPY %1(i64) + $d1 = COPY %2(i64) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -117,20 +117,20 @@ body: | ; CHECK-NEXT: BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (s64) from %stack.0) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (i64) from %stack.0) ; CHECK-NEXT: $d0 = COPY [[COPY1]] ; CHECK-NEXT: $d1 = COPY [[LDRDui]] ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %3:gpr(p0) = G_FRAME_INDEX %stack.0 ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp - $d0 = COPY %0(s64) + $d0 = COPY %0(i64) $x0 = COPY %3(p0) BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0 ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp - %1:fpr(s64) = COPY $d0 - %2:fpr(s64) = G_LOAD %3(p0) :: (load (s64) from %stack.0) - $d0 = COPY %1(s64) - $d1 = COPY %2(s64) + %1:fpr(i64) = COPY $d0 + %2:fpr(i64) = G_LOAD %3(p0) :: (load (i64) from %stack.0) + $d0 = COPY %1(i64) + $d1 = COPY %2(i64) RET_ReallyLR implicit $d0, implicit $d1 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir index cf227cbb6f33b..640f225ea7d90 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir @@ -28,7 +28,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[UCVTFd:%[0-9]+]]:fpr64 = UCVTFd [[COPY]], 12 ; CHECK-NEXT: $d1 = COPY [[UCVTFd]] - %0(s64) = COPY $d0 - %2(s64) = G_INTRINSIC intrinsic(@llvm.aarch64.neon.vcvtfxu2fp.f64), %0, 12 - $d1 = COPY %2(s64) + %0(i64) = COPY $d0 + %2(f64) = G_INTRINSIC intrinsic(@llvm.aarch64.neon.vcvtfxu2fp.f64), %0, 12 + $d1 = COPY %2(f64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ptr-add.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ptr-add.mir index 349513158e41c..90fbb993cc677 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ptr-add.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ptr-add.mir @@ -15,8 +15,8 @@ body: | ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY1]], 42, 0 ; CHECK-NEXT: $x0 = COPY [[ADDXri]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 42 - %2:gpr(p0) = G_PTR_ADD %0, %1(s64) + %1:gpr(i64) = G_CONSTANT i64 42 + %2:gpr(p0) = G_PTR_ADD %0, %1(i64) $x0 = COPY %2(p0) ... @@ -35,8 +35,8 @@ body: | ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY]], [[COPY1]] ; CHECK-NEXT: $x0 = COPY [[ADDXrr]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(p0) = G_PTR_ADD %0, %1(s64) + %1:gpr(i64) = COPY $x1 + %2:gpr(p0) = G_PTR_ADD %0, %1(i64) $x0 = COPY %2(p0) ... @@ -56,8 +56,8 @@ body: | ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY]], [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY [[ADDXrr]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 10000 - %2:gpr(p0) = G_PTR_ADD %0, %1(s64) + %1:gpr(i64) = G_CONSTANT i64 10000 + %2:gpr(p0) = G_PTR_ADD %0, %1(i64) $x0 = COPY %2(p0) ... @@ -76,8 +76,8 @@ body: | ; CHECK-NEXT: [[ADDv2i64_:%[0-9]+]]:fpr128 = ADDv2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ADDv2i64_]] %0:fpr(<2 x p0>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %3:fpr(<2 x p0>) = G_PTR_ADD %0, %1(<2 x s64>) + %1:fpr(<2 x i64>) = COPY $q1 + %3:fpr(<2 x p0>) = G_PTR_ADD %0, %1(<2 x i64>) $q0 = COPY %3(<2 x p0>) ... --- @@ -95,8 +95,8 @@ body: | ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[COPY1]], 10, 0, implicit-def dead $nzcv ; CHECK-NEXT: $x0 = COPY [[SUBSXri]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 -10 - %2:gpr(p0) = G_PTR_ADD %0, %1(s64) + %1:gpr(i64) = G_CONSTANT i64 -10 + %2:gpr(p0) = G_PTR_ADD %0, %1(i64) $x0 = COPY %2(p0) ... --- @@ -114,12 +114,12 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY %ptr ; CHECK-NEXT: %ptr_add:gpr64sp = ADDXrx [[COPY]], %reg0, 18 ; CHECK-NEXT: $x0 = COPY %ptr_add - %reg0:gpr(s32) = COPY $w0 + %reg0:gpr(i32) = COPY $w0 %ptr:gpr(p0) = COPY $x1 - %ext:gpr(s64) = G_ZEXT %reg0(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %ptr_add:gpr(p0) = G_PTR_ADD %ptr, %shift(s64) + %ext:gpr(i64) = G_ZEXT %reg0(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %ptr_add:gpr(p0) = G_PTR_ADD %ptr, %shift(i64) $x0 = COPY %ptr_add(p0) ... --- @@ -137,9 +137,9 @@ body: | ; CHECK-NEXT: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr [[COPY]], %src, implicit-def dead $nzcv ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] %0:gpr(p0) = COPY $x0 - %src:gpr(s64) = COPY $x1 - %1:gpr(s64) = G_CONSTANT i64 0 - %neg:gpr(s64) = G_SUB %1, %src - %2:gpr(p0) = G_PTR_ADD %0, %neg(s64) + %src:gpr(i64) = COPY $x1 + %1:gpr(i64) = G_CONSTANT i64 0 + %neg:gpr(i64) = G_SUB %1, %src + %2:gpr(p0) = G_PTR_ADD %0, %neg(i64) $x0 = COPY %2(p0) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir index b743cb9f7c578..e48664da8e97a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir @@ -16,14 +16,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<16 x s8>)) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<16 x i8>)) ; CHECK-NEXT: [[ADDVv16i8v:%[0-9]+]]:fpr8 = ADDVv16i8v [[LDRQui]] ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[ADDVv16i8v]], %subreg.bsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %1:fpr(<16 x i8>) = G_LOAD %0(p0) :: (load (<16 x s8>)) + %1:fpr(<16 x i8>) = G_LOAD %0(p0) :: (load (<16 x i8>)) %2:fpr(i8) = G_VECREDUCE_ADD %1(<16 x i8>) %4:gpr(i8) = COPY %2(i8) %3:gpr(i32) = G_ANYEXT %4(i8) @@ -47,14 +47,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<8 x s16>)) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<8 x i16>)) ; CHECK-NEXT: [[ADDVv8i16v:%[0-9]+]]:fpr16 = ADDVv8i16v [[LDRQui]] ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[ADDVv8i16v]], %subreg.hsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %1:fpr(<8 x i16>) = G_LOAD %0(p0) :: (load (<8 x s16>)) + %1:fpr(<8 x i16>) = G_LOAD %0(p0) :: (load (<8 x i16>)) %2:fpr(i16) = G_VECREDUCE_ADD %1(<8 x i16>) %4:gpr(i16) = COPY %2(i16) %3:gpr(i32) = G_ANYEXT %4(i16) @@ -78,12 +78,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x s32>)) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x i32>)) ; CHECK-NEXT: [[ADDVv4i32v:%[0-9]+]]:fpr32 = ADDVv4i32v [[LDRQui]] ; CHECK-NEXT: $w0 = COPY [[ADDVv4i32v]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %1:fpr(<4 x i32>) = G_LOAD %0(p0) :: (load (<4 x s32>)) + %1:fpr(<4 x i32>) = G_LOAD %0(p0) :: (load (<4 x i32>)) %2:fpr(i32) = G_VECREDUCE_ADD %1(<4 x i32>) $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 @@ -105,13 +105,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<2 x s32>)) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<2 x i32>)) ; CHECK-NEXT: [[ADDPv2i32_:%[0-9]+]]:fpr64 = ADDPv2i32 [[LDRDui]], [[LDRDui]] ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[ADDPv2i32_]].ssub ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %1:fpr(<2 x i32>) = G_LOAD %0(p0) :: (load (<2 x s32>)) + %1:fpr(<2 x i32>) = G_LOAD %0(p0) :: (load (<2 x i32>)) %2:fpr(i32) = G_VECREDUCE_ADD %1(<2 x i32>) $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 @@ -133,12 +133,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x i64>)) ; CHECK-NEXT: [[ADDPv2i64p:%[0-9]+]]:fpr64 = ADDPv2i64p [[LDRQui]] ; CHECK-NEXT: $x0 = COPY [[ADDPv2i64p]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 - %1:fpr(<2 x i64>) = G_LOAD %0(p0) :: (load (<2 x s64>)) + %1:fpr(<2 x i64>) = G_LOAD %0(p0) :: (load (<2 x i64>)) %2:fpr(i64) = G_VECREDUCE_ADD %1(<2 x i64>) $x0 = COPY %2(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir index dc7c975edb488..3f7dc2a8b7349 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir @@ -13,14 +13,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRBBui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(p0) = COPY $x0 - %2:gpr(s8) = G_LOAD %1(p0) :: (load (s8)) - %3:gpr(s32) = G_ZEXT %2(s8) - $w0 = COPY %3(s32) + %2:gpr(i8) = G_LOAD %1(p0) :: (load (i8)) + %3:gpr(i32) = G_ZEXT %2(i8) + $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 ... @@ -37,14 +37,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(p0) = COPY $x0 - %2:gpr(s16) = G_LOAD %1(p0) :: (load (s16)) - %3:gpr(s32) = G_ZEXT %2(s16) - $w0 = COPY %3(s32) + %2:gpr(i16) = G_LOAD %1(p0) :: (load (i16)) + %3:gpr(i32) = G_ZEXT %2(i16) + $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext.mir index f5a94c7ad51fe..f4ce1af7f5a27 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext.mir @@ -52,8 +52,8 @@ body: | ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64 = UBFMXri [[SUBREG_TO_REG]], 0, 15 ; CHECK-NEXT: $x0 = COPY [[UBFMXri]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr(s16) = G_IMPLICIT_DEF - %3:gpr(i64) = G_ZEXT %0(s16) + %0:gpr(i16) = G_IMPLICIT_DEF + %3:gpr(i64) = G_ZEXT %0(i16) $x0 = COPY %3(i64) RET_ReallyLR implicit $x0 @@ -104,7 +104,7 @@ body: | ; CHECK-NEXT: $x0 = COPY %zext ; CHECK-NEXT: RET_ReallyLR implicit $x0 %copy:gpr(i32) = COPY $w0 - %bitcast0:gpr(<4 x s8>) = G_BITCAST %copy(i32) + %bitcast0:gpr(<4 x i8>) = G_BITCAST %copy(i32) %bitcast1:gpr(i32) = G_BITCAST %bitcast0 %zext:gpr(i64) = G_ZEXT %bitcast1(i32) $x0 = COPY %zext(i64) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-rev.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-rev.mir index d011143667e48..a95d9e45a6505 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-rev.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-rev.mir @@ -27,9 +27,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV64v2i32 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<2 x s32>) = COPY $d0 - %rev:fpr(<2 x s32>) = G_REV64 %copy - $d0 = COPY %rev(<2 x s32>) + %copy:fpr(<2 x i32>) = COPY $d0 + %rev:fpr(<2 x i32>) = G_REV64 %copy + $d0 = COPY %rev(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -49,9 +49,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV64v4i16 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<4 x s16>) = COPY $d0 - %rev:fpr(<4 x s16>) = G_REV64 %copy - $d0 = COPY %rev(<4 x s16>) + %copy:fpr(<4 x i16>) = COPY $d0 + %rev:fpr(<4 x i16>) = G_REV64 %copy + $d0 = COPY %rev(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -71,9 +71,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV64v4i32 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<4 x s32>) = COPY $q0 - %rev:fpr(<4 x s32>) = G_REV64 %copy - $q0 = COPY %rev(<4 x s32>) + %copy:fpr(<4 x i32>) = COPY $q0 + %rev:fpr(<4 x i32>) = G_REV64 %copy + $q0 = COPY %rev(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -93,9 +93,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV64v8i8 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<8 x s8>) = COPY $d0 - %rev:fpr(<8 x s8>) = G_REV64 %copy - $d0 = COPY %rev(<8 x s8>) + %copy:fpr(<8 x i8>) = COPY $d0 + %rev:fpr(<8 x i8>) = G_REV64 %copy + $d0 = COPY %rev(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -115,9 +115,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV64v8i16 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<8 x s16>) = COPY $q0 - %rev:fpr(<8 x s16>) = G_REV64 %copy - $q0 = COPY %rev(<8 x s16>) + %copy:fpr(<8 x i16>) = COPY $q0 + %rev:fpr(<8 x i16>) = G_REV64 %copy + $q0 = COPY %rev(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -137,9 +137,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV64v16i8 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<16 x s8>) = COPY $q0 - %rev:fpr(<16 x s8>) = G_REV64 %copy - $q0 = COPY %rev(<16 x s8>) + %copy:fpr(<16 x i8>) = COPY $q0 + %rev:fpr(<16 x i8>) = G_REV64 %copy + $q0 = COPY %rev(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -159,9 +159,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV32v4i16 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<4 x s16>) = COPY $d0 - %rev:fpr(<4 x s16>) = G_REV32 %copy - $d0 = COPY %rev(<4 x s16>) + %copy:fpr(<4 x i16>) = COPY $d0 + %rev:fpr(<4 x i16>) = G_REV32 %copy + $d0 = COPY %rev(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -181,9 +181,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV32v8i8 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<8 x s8>) = COPY $d0 - %rev:fpr(<8 x s8>) = G_REV32 %copy - $d0 = COPY %rev(<8 x s8>) + %copy:fpr(<8 x i8>) = COPY $d0 + %rev:fpr(<8 x i8>) = G_REV32 %copy + $d0 = COPY %rev(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -203,9 +203,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV32v8i16 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<8 x s16>) = COPY $q0 - %rev:fpr(<8 x s16>) = G_REV32 %copy - $q0 = COPY %rev(<8 x s16>) + %copy:fpr(<8 x i16>) = COPY $q0 + %rev:fpr(<8 x i16>) = G_REV32 %copy + $q0 = COPY %rev(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -225,9 +225,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV32v16i8 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<16 x s8>) = COPY $q0 - %rev:fpr(<16 x s8>) = G_REV32 %copy - $q0 = COPY %rev(<16 x s8>) + %copy:fpr(<16 x i8>) = COPY $q0 + %rev:fpr(<16 x i8>) = G_REV32 %copy + $q0 = COPY %rev(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -247,11 +247,11 @@ body: | ; CHECK-NEXT: %rev2:fpr64 = REV16v8i8 %copy ; CHECK-NEXT: $d0 = COPY %rev2 ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<8 x s8>) = COPY $d0 - %rev1:fpr(<4 x s16>) = G_BITCAST %copy - %rev2:fpr(<4 x s16>) = G_BSWAP %rev1 - %rev:fpr(<8 x s8>) = G_BITCAST %rev2 - $d0 = COPY %rev(<8 x s8>) + %copy:fpr(<8 x i8>) = COPY $d0 + %rev1:fpr(<4 x i16>) = G_BITCAST %copy + %rev2:fpr(<4 x i16>) = G_BSWAP %rev1 + %rev:fpr(<8 x i8>) = G_BITCAST %rev2 + $d0 = COPY %rev(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -271,9 +271,9 @@ body: | ; CHECK-NEXT: %rev2:fpr128 = REV16v16i8 %copy ; CHECK-NEXT: $q0 = COPY %rev2 ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<16 x s8>) = COPY $q0 - %rev1:fpr(<8 x s16>) = G_BITCAST %copy - %rev2:fpr(<8 x s16>) = G_BSWAP %rev1 - %rev:fpr(<16 x s8>) = G_BITCAST %rev2 - $q0 = COPY %rev(<16 x s8>) + %copy:fpr(<16 x i8>) = COPY $q0 + %rev1:fpr(<8 x i16>) = G_BITCAST %copy + %rev2:fpr(<8 x i16>) = G_BSWAP %rev1 + %rev:fpr(<16 x i8>) = G_BITCAST %rev2 + $q0 = COPY %rev(<16 x i8>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-sadde.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-sadde.mir index e98ab4af57097..893236c83c57d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-sadde.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-sadde.mir @@ -23,12 +23,12 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADCSXr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s64), %4:gpr(s32) = G_SADDE %0, %1, %2 - $x0 = COPY %3(s64) - $w1 = COPY %4(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i64), %4:gpr(i32) = G_SADDE %0, %1, %2 + $x0 = COPY %3(i64) + $w1 = COPY %4(i32) RET_ReallyLR implicit $x0, implicit $w1 ... ... @@ -54,12 +54,12 @@ body: | ; CHECK-NEXT: $w0 = COPY [[ADCSWr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32), %4:gpr(s32) = G_SADDE %0, %1, %2 - $w0 = COPY %3(s32) - $w1 = COPY %4(s32) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32), %4:gpr(i32) = G_SADDE %0, %1, %2 + $w0 = COPY %3(i32) + $w1 = COPY %4(i32) RET_ReallyLR implicit $w0, implicit $w1 ... ... @@ -85,14 +85,14 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADDSXrr]] ; CHECK-NEXT: $x1 = COPY [[ADCSXr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %8:gpr(s64), %12:gpr(s32) = G_UADDO %0, %2 - %9:gpr(s64), %13:gpr(s32) = G_SADDE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %8:gpr(i64), %12:gpr(i32) = G_UADDO %0, %2 + %9:gpr(i64), %13:gpr(i32) = G_SADDE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -120,15 +120,15 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADCSXr]] ; CHECK-NEXT: $x1 = COPY [[ADCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %6:gpr(s32) = G_CONSTANT i32 1 - %8:gpr(s64), %12:gpr(s32) = G_UADDE %0, %2, %6 - %9:gpr(s64), %13:gpr(s32) = G_SADDE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %6:gpr(i32) = G_CONSTANT i32 1 + %8:gpr(i64), %12:gpr(i32) = G_UADDE %0, %2, %6 + %9:gpr(i64), %13:gpr(i32) = G_SADDE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -160,19 +160,19 @@ body: | ; CHECK-NEXT: $x1 = COPY [[ADCSXr]] ; CHECK-NEXT: $x2 = COPY [[ADCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %4:gpr(s64) = COPY $x4 - %5:gpr(s64) = COPY $x5 - %6:gpr(s64) = COPY $x6 - %7:gpr(s64), %11:gpr(s32) = G_UADDO %0, %4 - %8:gpr(s64), %12:gpr(s32) = G_UADDE %1, %5, %11 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %4:gpr(i64) = COPY $x4 + %5:gpr(i64) = COPY $x5 + %6:gpr(i64) = COPY $x6 + %7:gpr(i64), %11:gpr(i32) = G_UADDO %0, %4 + %8:gpr(i64), %12:gpr(i32) = G_UADDE %1, %5, %11 ; carry-in is not produced by previous instruction - %9:gpr(s64), %13:gpr(s32) = G_SADDE %2, %6, %11 - $x0 = COPY %7(s64) - $x1 = COPY %8(s64) - $x2 = COPY %9(s64) + %9:gpr(i64), %13:gpr(i32) = G_SADDE %2, %6, %11 + $x0 = COPY %7(i64) + $x1 = COPY %8(i64) + $x2 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 ... ... @@ -197,12 +197,12 @@ body: | ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 7, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %4:gpr(s64), %5:gpr(s32) = G_UADDO %0, %2 - %6:gpr(s64), %7:gpr(s32) = G_SADDE %1, %3, %5 - $w0 = COPY %7(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %4:gpr(i64), %5:gpr(i32) = G_UADDO %0, %2 + %6:gpr(i64), %7:gpr(i32) = G_SADDE %1, %3, %5 + $w0 = COPY %7(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-saddo.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-saddo.mir index fe272c68d450f..4bf7128418ae6 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-saddo.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-saddo.mir @@ -22,9 +22,9 @@ body: | ; CHECK-NEXT: $w0 = COPY [[ADDSWrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %3:gpr(s32), %4:gpr(s32) = G_SADDO %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %3:gpr(i32), %4:gpr(i32) = G_SADDO %0, %1 $w0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $w0, implicit $w1 @@ -50,9 +50,9 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADDSXrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %3:gpr(s64), %4:gpr(s32) = G_SADDO %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %3:gpr(i64), %4:gpr(i32) = G_SADDO %0, %1 $x0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $x0, implicit $w1 @@ -75,10 +75,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 16 - %add:gpr(s32), %overflow:gpr(s32) = G_SADDO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 16 + %add:gpr(i32), %overflow:gpr(i32) = G_SADDO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -100,12 +100,12 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWrs %copy1, %copy2, 16, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy1:gpr(s32) = COPY $w0 - %copy2:gpr(s32) = COPY $w1 - %constant:gpr(s32) = G_CONSTANT i32 16 - %shift:gpr(s32) = G_SHL %copy2(s32), %constant(s32) - %add:gpr(s32), %overflow:gpr(s32) = G_SADDO %copy1, %shift - $w0 = COPY %add(s32) + %copy1:gpr(i32) = COPY $w0 + %copy2:gpr(i32) = COPY $w1 + %constant:gpr(i32) = G_CONSTANT i32 16 + %shift:gpr(i32) = G_SHL %copy2(i32), %constant(i32) + %add:gpr(i32), %overflow:gpr(i32) = G_SADDO %copy1, %shift + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -126,10 +126,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 -16 - %add:gpr(s32), %overflow:gpr(s32) = G_SADDO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 -16 + %add:gpr(i32), %overflow:gpr(i32) = G_SADDO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -151,11 +151,11 @@ body: | ; CHECK-NEXT: %add:gpr64 = ADDSXrx %reg0, %reg1, 18, implicit-def $nzcv ; CHECK-NEXT: $x0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:gpr(s64) = COPY $x0 - %reg1:gpr(s32) = COPY $w0 - %ext:gpr(s64) = G_ZEXT %reg1(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %add:gpr(s64), %flags:gpr(s32) = G_SADDO %reg0, %shift - $x0 = COPY %add(s64) + %reg0:gpr(i64) = COPY $x0 + %reg1:gpr(i32) = COPY $w0 + %ext:gpr(i64) = G_ZEXT %reg1(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %add:gpr(i64), %flags:gpr(i32) = G_SADDO %reg0, %shift + $x0 = COPY %add(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir index bbf6239b510cf..22cf6b4bab615 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir @@ -17,10 +17,10 @@ body: | ; CHECK-NEXT: %sbfx:gpr32 = SBFMWri %copy, 0, 9 ; CHECK-NEXT: $w0 = COPY %sbfx ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 0 - %cst2:gpr(s32) = G_CONSTANT i32 10 - %sbfx:gpr(s32) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 0 + %cst2:gpr(i32) = G_CONSTANT i32 10 + %sbfx:gpr(i32) = G_SBFX %copy, %cst1, %cst2 $w0 = COPY %sbfx RET_ReallyLR implicit $w0 @@ -40,10 +40,10 @@ body: | ; CHECK-NEXT: %sbfx:gpr64 = SBFMXri %copy, 0, 9 ; CHECK-NEXT: $x0 = COPY %sbfx ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %copy:gpr(s64) = COPY $x0 - %cst1:gpr(s64) = G_CONSTANT i64 0 - %cst2:gpr(s64) = G_CONSTANT i64 10 - %sbfx:gpr(s64) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i64) = COPY $x0 + %cst1:gpr(i64) = G_CONSTANT i64 0 + %cst2:gpr(i64) = G_CONSTANT i64 10 + %sbfx:gpr(i64) = G_SBFX %copy, %cst1, %cst2 $x0 = COPY %sbfx RET_ReallyLR implicit $x0 @@ -65,10 +65,10 @@ body: | ; CHECK-NEXT: %sbfx:gpr32 = SBFMWri %copy, 31, 31 ; CHECK-NEXT: $w0 = COPY %sbfx ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 31 - %cst2:gpr(s32) = G_CONSTANT i32 1 - %sbfx:gpr(s32) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 31 + %cst2:gpr(i32) = G_CONSTANT i32 1 + %sbfx:gpr(i32) = G_SBFX %copy, %cst1, %cst2 $w0 = COPY %sbfx RET_ReallyLR implicit $w0 --- @@ -85,10 +85,10 @@ body: | ; CHECK: %sbfx:gpr32 = SBFMWri %copy, 10, 14 ; CHECK: $w0 = COPY %sbfx ; CHECK: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 10 - %cst2:gpr(s32) = G_CONSTANT i32 5 - %sbfx:gpr(s32) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 10 + %cst2:gpr(i32) = G_CONSTANT i32 5 + %sbfx:gpr(i32) = G_SBFX %copy, %cst1, %cst2 $w0 = COPY %sbfx RET_ReallyLR implicit $w0 --- @@ -105,9 +105,9 @@ body: | ; CHECK: %sbfx:gpr64 = SBFMXri %copy, 10, 14 ; CHECK: $x0 = COPY %sbfx ; CHECK: RET_ReallyLR implicit $x0 - %copy:gpr(s64) = COPY $x0 - %cst1:gpr(s64) = G_CONSTANT i64 10 - %cst2:gpr(s64) = G_CONSTANT i64 5 - %sbfx:gpr(s64) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i64) = COPY $x0 + %cst1:gpr(i64) = G_CONSTANT i64 10 + %cst2:gpr(i64) = G_CONSTANT i64 5 + %sbfx:gpr(i64) = G_SBFX %copy, %cst1, %cst2 $x0 = COPY %sbfx RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-merge.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-merge.mir index 42b1c61949b94..85e5b1bb9e957 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-merge.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-merge.mir @@ -29,8 +29,8 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG1:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[COPY1]], %subreg.sub_32 ; CHECK-NEXT: [[BFMXri:%[0-9]+]]:gpr64 = BFMXri [[SUBREG_TO_REG]], [[SUBREG_TO_REG1]], 32, 31 ; CHECK-NEXT: $x0 = COPY [[BFMXri]] - %0(s32) = COPY $w0 - %1(s32) = COPY $w1 - %2(s64) = G_MERGE_VALUES %0(s32), %1(s32) - $x0 = COPY %2(s64) + %0(i32) = COPY $w0 + %1(i32) = COPY $w1 + %2(i64) = G_MERGE_VALUES %0(i32), %1(i32) + $x0 = COPY %2(i64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-sextload.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-sextload.mir index d2bf5839f1be7..6aca3c31774aa 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-sextload.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-sextload.mir @@ -21,10 +21,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRSHWui:%[0-9]+]]:gpr32 = LDRSHWui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRSHWui:%[0-9]+]]:gpr32 = LDRSHWui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRSHWui]] %0:gpr(p0) = COPY $x0 - %1:gpr(i32) = G_SEXTLOAD %0 :: (load (s16) from %ir.addr) + %1:gpr(i32) = G_SEXTLOAD %0 :: (load (i16) from %ir.addr) $w0 = COPY %1(i32) ... @@ -41,11 +41,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: [[SBFMWri:%[0-9]+]]:gpr32 = SBFMWri [[LDRHHui]], 0, 15 ; CHECK-NEXT: $w0 = COPY [[SBFMWri]] %0:gpr(p0) = COPY $x0 - %1:gpr(i16) = G_LOAD %0 :: (load (s16) from %ir.addr) + %1:gpr(i16) = G_LOAD %0 :: (load (i16) from %ir.addr) %2:gpr(i32) = G_SEXT %1 $w0 = COPY %2(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir index 345cc774f9963..666e7c059a8e1 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir @@ -59,10 +59,10 @@ body: | ; CHECK: [[COPY2:%[0-9]+]]:fpr64 = COPY [[TBLv16i8One]].dsub ; CHECK: $d0 = COPY [[COPY2]] ; CHECK: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 0) - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 0) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -90,10 +90,10 @@ body: | ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]] ; CHECK: $q0 = COPY [[TBLv16i8Two]] ; CHECK: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 1, 3, 0) - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 1, 3, 0) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -121,10 +121,10 @@ body: | ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]] ; CHECK: $q0 = COPY [[TBLv16i8Two]] ; CHECK: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(5, 7, 1, 0) - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(5, 7, 1, 0) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -152,10 +152,10 @@ body: | ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]] ; CHECK: $q0 = COPY [[TBLv16i8Two]] ; CHECK: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(1, 0) - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(1, 0) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-shufflevec-undef-mask-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-shufflevec-undef-mask-elt.mir index a5ac0b7ff8626..86350664abf63 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-shufflevec-undef-mask-elt.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-shufflevec-undef-mask-elt.mir @@ -36,12 +36,12 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[TBLv16i8One]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %6:gpr(s32) = G_IMPLICIT_DEF - %7:gpr(s32) = G_IMPLICIT_DEF - %2:fpr(<2 x s32>) = G_BUILD_VECTOR %6(s32), %7(s32) - %1:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, undef) - $d0 = COPY %1(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %6:gpr(i32) = G_IMPLICIT_DEF + %7:gpr(i32) = G_IMPLICIT_DEF + %2:fpr(<2 x i32>) = G_BUILD_VECTOR %6(i32), %7(i32) + %1:fpr(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %2, shufflemask(1, undef) + $d0 = COPY %1(<2 x i32>) RET_ReallyLR implicit $d0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ssube.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ssube.mir index a9da51781efbe..1b3ae63e0c9c4 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ssube.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ssube.mir @@ -23,12 +23,12 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SBCSXr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s64), %4:gpr(s32) = G_SSUBE %0, %1, %2 - $x0 = COPY %3(s64) - $w1 = COPY %4(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i64), %4:gpr(i32) = G_SSUBE %0, %1, %2 + $x0 = COPY %3(i64) + $w1 = COPY %4(i32) RET_ReallyLR implicit $x0, implicit $w1 ... ... @@ -54,12 +54,12 @@ body: | ; CHECK-NEXT: $w0 = COPY [[SBCSWr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32), %4:gpr(s32) = G_SSUBE %0, %1, %2 - $w0 = COPY %3(s32) - $w1 = COPY %4(s32) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32), %4:gpr(i32) = G_SSUBE %0, %1, %2 + $w0 = COPY %3(i32) + $w1 = COPY %4(i32) RET_ReallyLR implicit $w0, implicit $w1 ... ... @@ -85,14 +85,14 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] ; CHECK-NEXT: $x1 = COPY [[SBCSXr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %8:gpr(s64), %12:gpr(s32) = G_USUBO %0, %2 - %9:gpr(s64), %13:gpr(s32) = G_SSUBE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %8:gpr(i64), %12:gpr(i32) = G_USUBO %0, %2 + %9:gpr(i64), %13:gpr(i32) = G_SSUBE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -120,15 +120,15 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SBCSXr]] ; CHECK-NEXT: $x1 = COPY [[SBCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %6:gpr(s32) = G_CONSTANT i32 1 - %8:gpr(s64), %12:gpr(s32) = G_USUBE %0, %2, %6 - %9:gpr(s64), %13:gpr(s32) = G_SSUBE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %6:gpr(i32) = G_CONSTANT i32 1 + %8:gpr(i64), %12:gpr(i32) = G_USUBE %0, %2, %6 + %9:gpr(i64), %13:gpr(i32) = G_SSUBE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -160,19 +160,19 @@ body: | ; CHECK-NEXT: $x1 = COPY [[SBCSXr]] ; CHECK-NEXT: $x2 = COPY [[SBCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %4:gpr(s64) = COPY $x4 - %5:gpr(s64) = COPY $x5 - %6:gpr(s64) = COPY $x6 - %7:gpr(s64), %11:gpr(s32) = G_USUBO %0, %4 - %8:gpr(s64), %12:gpr(s32) = G_USUBE %1, %5, %11 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %4:gpr(i64) = COPY $x4 + %5:gpr(i64) = COPY $x5 + %6:gpr(i64) = COPY $x6 + %7:gpr(i64), %11:gpr(i32) = G_USUBO %0, %4 + %8:gpr(i64), %12:gpr(i32) = G_USUBE %1, %5, %11 ; carry-in is not produced by previous instruction - %9:gpr(s64), %13:gpr(s32) = G_SSUBE %2, %6, %11 - $x0 = COPY %7(s64) - $x1 = COPY %8(s64) - $x2 = COPY %9(s64) + %9:gpr(i64), %13:gpr(i32) = G_SSUBE %2, %6, %11 + $x0 = COPY %7(i64) + $x1 = COPY %8(i64) + $x2 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 ... ... @@ -197,12 +197,12 @@ body: | ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 7, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %4:gpr(s64), %5:gpr(s32) = G_USUBO %0, %2 - %6:gpr(s64), %7:gpr(s32) = G_SSUBE %1, %3, %5 - $w0 = COPY %7(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %4:gpr(i64), %5:gpr(i32) = G_USUBO %0, %2 + %6:gpr(i64), %7:gpr(i32) = G_SSUBE %1, %3, %5 + $w0 = COPY %7(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ssubo.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ssubo.mir index 700a7e298ec5f..c2b116b3f77ea 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ssubo.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ssubo.mir @@ -22,9 +22,9 @@ body: | ; CHECK-NEXT: $w0 = COPY [[SUBSWrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %3:gpr(s32), %4:gpr(s32) = G_SSUBO %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %3:gpr(i32), %4:gpr(i32) = G_SSUBO %0, %1 $w0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $w0, implicit $w1 @@ -50,9 +50,9 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %3:gpr(s64), %4:gpr(s32) = G_SSUBO %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %3:gpr(i64), %4:gpr(i32) = G_SSUBO %0, %1 $x0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $x0, implicit $w1 @@ -75,10 +75,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 16 - %add:gpr(s32), %overflow:gpr(s32) = G_SSUBO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 16 + %add:gpr(i32), %overflow:gpr(i32) = G_SSUBO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -100,12 +100,12 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWrs %copy1, %copy2, 16, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy1:gpr(s32) = COPY $w0 - %copy2:gpr(s32) = COPY $w1 - %constant:gpr(s32) = G_CONSTANT i32 16 - %shift:gpr(s32) = G_SHL %copy2(s32), %constant(s32) - %add:gpr(s32), %overflow:gpr(s32) = G_SSUBO %copy1, %shift - $w0 = COPY %add(s32) + %copy1:gpr(i32) = COPY $w0 + %copy2:gpr(i32) = COPY $w1 + %constant:gpr(i32) = G_CONSTANT i32 16 + %shift:gpr(i32) = G_SHL %copy2(i32), %constant(i32) + %add:gpr(i32), %overflow:gpr(i32) = G_SSUBO %copy1, %shift + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -126,10 +126,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 -16 - %add:gpr(s32), %overflow:gpr(s32) = G_SSUBO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 -16 + %add:gpr(i32), %overflow:gpr(i32) = G_SSUBO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -151,11 +151,11 @@ body: | ; CHECK-NEXT: %add:gpr64 = SUBSXrx %reg0, %reg1, 18, implicit-def $nzcv ; CHECK-NEXT: $x0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:gpr(s64) = COPY $x0 - %reg1:gpr(s32) = COPY $w0 - %ext:gpr(s64) = G_ZEXT %reg1(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %add:gpr(s64), %flags:gpr(s32) = G_SSUBO %reg0, %shift - $x0 = COPY %add(s64) + %reg0:gpr(i64) = COPY $x0 + %reg1:gpr(i32) = COPY $w0 + %ext:gpr(i64) = G_ZEXT %reg1(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %add:gpr(i64), %flags:gpr(i32) = G_SSUBO %reg0, %shift + $x0 = COPY %add(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-st2.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-st2.mir index 3503b8e13c588..1dd0e8f1288e5 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-st2.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-st2.mir @@ -18,12 +18,12 @@ body: | ; CHECK-NEXT: %src1:fpr64 = COPY $d0 ; CHECK-NEXT: %src2:fpr64 = COPY $d1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST2Twov8b [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST2Twov8b [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<8 x s8>) = COPY $d0 - %src2:fpr(<8 x s8>) = COPY $d1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<8 x s8>), %src2(<8 x s8>), %ptr(p0) :: (store (<2 x s64>)) + %src1:fpr(<8 x i8>) = COPY $d0 + %src2:fpr(<8 x i8>) = COPY $d1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<8 x i8>), %src2(<8 x i8>), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -44,12 +44,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov16b [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov16b [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<16 x s8>) = COPY $q0 - %src2:fpr(<16 x s8>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<16 x s8>), %src2(<16 x s8>), %ptr(p0) :: (store (<4 x s64>)) + %src1:fpr(<16 x i8>) = COPY $q0 + %src2:fpr(<16 x i8>) = COPY $q1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<16 x i8>), %src2(<16 x i8>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -70,12 +70,12 @@ body: | ; CHECK-NEXT: %src1:fpr64 = COPY $d0 ; CHECK-NEXT: %src2:fpr64 = COPY $d1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST2Twov4h [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST2Twov4h [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<4 x s16>) = COPY $d0 - %src2:fpr(<4 x s16>) = COPY $d1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<4 x s16>), %src2(<4 x s16>), %ptr(p0) :: (store (<2 x s64>)) + %src1:fpr(<4 x i16>) = COPY $d0 + %src2:fpr(<4 x i16>) = COPY $d1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<4 x i16>), %src2(<4 x i16>), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -96,12 +96,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov8h [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov8h [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<8 x s16>) = COPY $q0 - %src2:fpr(<8 x s16>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<8 x s16>), %src2(<8 x s16>), %ptr(p0) :: (store (<4 x s64>)) + %src1:fpr(<8 x i16>) = COPY $q0 + %src2:fpr(<8 x i16>) = COPY $q1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<8 x i16>), %src2(<8 x i16>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -121,12 +121,12 @@ body: | ; CHECK-NEXT: %src1:fpr64 = COPY $d0 ; CHECK-NEXT: %src2:fpr64 = COPY $d1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST2Twov2s [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST2Twov2s [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<2 x s32>) = COPY $d0 - %src2:fpr(<2 x s32>) = COPY $d1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x s32>), %src2(<2 x s32>), %ptr(p0) :: (store (<2 x s64>)) + %src1:fpr(<2 x i32>) = COPY $d0 + %src2:fpr(<2 x i32>) = COPY $d1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x i32>), %src2(<2 x i32>), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -146,12 +146,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov4s [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov4s [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<4 x s32>) = COPY $q0 - %src2:fpr(<4 x s32>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<4 x s32>), %src2(<4 x s32>), %ptr(p0) :: (store (<4 x s64>)) + %src1:fpr(<4 x i32>) = COPY $q0 + %src2:fpr(<4 x i32>) = COPY $q1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<4 x i32>), %src2(<4 x i32>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -171,12 +171,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov2d [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov2d [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<2 x s64>) = COPY $q0 - %src2:fpr(<2 x s64>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x s64>), %src2(<2 x s64>), %ptr(p0) :: (store (<4 x s64>)) + %src1:fpr(<2 x i64>) = COPY $q0 + %src2:fpr(<2 x i64>) = COPY $q1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x i64>), %src2(<2 x i64>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -196,12 +196,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov2d [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov2d [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 %src1:fpr(<2 x p0>) = COPY $q0 %src2:fpr(<2 x p0>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x p0>), %src2(<2 x p0>), %ptr(p0) :: (store (<4 x s64>)) + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x p0>), %src2(<2 x p0>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -221,12 +221,12 @@ body: | ; CHECK-NEXT: %src1:gpr64all = COPY $x0 ; CHECK-NEXT: %src2:gpr64all = COPY $x1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST1Twov1d [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST1Twov1d [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:gpr(s64) = COPY $x0 - %src2:gpr(s64) = COPY $x1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(s64), %src2(s64), %ptr(p0) :: (store (<2 x s64>)) + %src1:gpr(i64) = COPY $x0 + %src2:gpr(i64) = COPY $x1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(i64), %src2(i64), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -246,12 +246,12 @@ body: | ; CHECK-NEXT: %src1:gpr64all = COPY $x0 ; CHECK-NEXT: %src2:gpr64all = COPY $x1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST1Twov1d [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST1Twov1d [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 %src1:gpr(p0) = COPY $x0 %src2:gpr(p0) = COPY $x1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(p0), %src2(p0), %ptr(p0) :: (store (<2 x s64>)) + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(p0), %src2(p0), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir index df13c02374fed..10150a882e9de 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir @@ -60,7 +60,7 @@ body: | bb.0: liveins: $x0 %0:gpr(p0) = COPY $x0 - %const:gpr(s64) = G_CONSTANT i64 -8 + %const:gpr(i64) = G_CONSTANT i64 -8 %1:gpr(p0) = G_PTRMASK %0, %const $x0 = COPY %1(p0) ... @@ -139,16 +139,16 @@ body: | bb.0: liveins: $w0, $x0 - %0(s32) = COPY $w0 - %1(s32) = G_ICMP intpred(eq), %0, %0 + %0(i32) = COPY $w0 + %1(i32) = G_ICMP intpred(eq), %0, %0 $w0 = COPY %1 - %2(s64) = COPY $x0 - %3(s32) = G_ICMP intpred(uge), %2, %2 + %2(i64) = COPY $x0 + %3(i32) = G_ICMP intpred(uge), %2, %2 $w0 = COPY %3 %4(p0) = COPY $x0 - %5(s32) = G_ICMP intpred(ne), %4, %4 + %5(i32) = G_ICMP intpred(ne), %4, %4 $w0 = COPY %5 ... @@ -184,12 +184,12 @@ body: | bb.0: liveins: $w0, $x0 - %0(s32) = COPY $s0 - %1(s32) = G_FCMP floatpred(one), %0, %0 + %0(f32) = COPY $s0 + %1(i32) = G_FCMP floatpred(one), %0, %0 $w0 = COPY %1 - %2(s64) = COPY $d0 - %3(s32) = G_FCMP floatpred(uge), %2, %2 + %2(f64) = COPY $d0 + %3(i32) = G_FCMP floatpred(uge), %2, %2 $w0 = COPY %3 ... @@ -219,12 +219,12 @@ body: | bb.0: liveins: $s0, $w0 successors: %bb.1 - %0(s32) = COPY $s0 - %3:gpr(s32) = COPY $w0 + %0(i32) = COPY $s0 + %3:gpr(i32) = COPY $w0 bb.1: successors: %bb.1, %bb.2 - %2(s32) = PHI %0, %bb.0, %2, %bb.1 + %2(i32) = PHI %0, %bb.0, %2, %bb.1 G_BRCOND %3, %bb.1 bb.2: @@ -272,17 +272,17 @@ registers: body: | bb.0: liveins: $w0, $w1, $w2 - %0:gpr(s32) = COPY $w0 + %0:gpr(i32) = COPY $w0 - %1(s32) = COPY $w1 - %2(s32) = COPY $w2 - %3(s32) = G_SELECT %0, %1, %2 - $w0 = COPY %3(s32) + %1(i32) = COPY $w1 + %2(i32) = COPY $w2 + %3(i32) = G_SELECT %0, %1, %2 + $w0 = COPY %3(i32) - %4(s64) = COPY $x0 - %5(s64) = COPY $x1 - %6(s64) = G_SELECT %0, %4, %5 - $x0 = COPY %6(s64) + %4(i64) = COPY $x0 + %5(i64) = COPY $x1 + %6(i64) = G_SELECT %0, %4, %5 + $x0 = COPY %6(i64) %7(p0) = COPY $x0 %8(p0) = COPY $x1 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-stlxr-intrin.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-stlxr-intrin.mir index 857ed9b3efbd3..f75aa7766131c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-stlxr-intrin.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-stlxr-intrin.mir @@ -28,12 +28,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x2 - ; CHECK-NEXT: early-clobber %2:gpr32 = STLXRX [[COPY]], [[COPY1]] :: (volatile store (s64) into %ir.addr) + ; CHECK-NEXT: early-clobber %2:gpr32 = STLXRX [[COPY]], [[COPY1]] :: (volatile store (i64) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %2 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(i64) = COPY $x1 %2:gpr(p0) = COPY $x2 - %3:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %1(i64), %2(p0) :: (volatile store (s64) into %ir.addr) + %3:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %1(i64), %2(p0) :: (volatile store (i64) into %ir.addr) $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 @@ -52,13 +52,13 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x2 - ; CHECK-NEXT: early-clobber %3:gpr32 = STLXRW [[COPY]], [[COPY1]] :: (volatile store (s32) into %ir.addr) + ; CHECK-NEXT: early-clobber %3:gpr32 = STLXRW [[COPY]], [[COPY1]] :: (volatile store (i32) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(i32) = COPY $w1 %2:gpr(p0) = COPY $x2 %3:gpr(i64) = G_ZEXT %1(i32) - %4:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %3(i64), %2(p0) :: (volatile store (s32) into %ir.addr) + %4:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %3(i64), %2(p0) :: (volatile store (i32) into %ir.addr) $w0 = COPY %4(i32) RET_ReallyLR implicit $w0 @@ -81,7 +81,7 @@ body: | ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[INSERT_SUBREG]].sub_32 - ; CHECK-NEXT: early-clobber %5:gpr32 = STLXRB [[COPY2]], [[COPY1]] :: (volatile store (s8) into %ir.addr) + ; CHECK-NEXT: early-clobber %5:gpr32 = STLXRB [[COPY2]], [[COPY1]] :: (volatile store (i8) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %5 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %3:gpr(i32) = COPY $w1 @@ -89,7 +89,7 @@ body: | %6:gpr(i64) = G_CONSTANT i64 255 %7:gpr(i64) = G_ANYEXT %3(i32) %4:gpr(i64) = G_AND %7, %6 - %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %4(i64), %2(p0) :: (volatile store (s8) into %ir.addr) + %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %4(i64), %2(p0) :: (volatile store (i8) into %ir.addr) $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 @@ -112,7 +112,7 @@ body: | ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[INSERT_SUBREG]].sub_32 - ; CHECK-NEXT: early-clobber %5:gpr32 = STLXRH [[COPY2]], [[COPY1]] :: (volatile store (s16) into %ir.addr) + ; CHECK-NEXT: early-clobber %5:gpr32 = STLXRH [[COPY2]], [[COPY1]] :: (volatile store (i16) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %5 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %3:gpr(i32) = COPY $w1 @@ -120,6 +120,6 @@ body: | %6:gpr(i64) = G_CONSTANT i64 65535 %7:gpr(i64) = G_ANYEXT %3(i32) %4:gpr(i64) = G_AND %7, %6 - %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %4(i64), %2(p0) :: (volatile store (s16) into %ir.addr) + %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %4(i64), %2(p0) :: (volatile store (i16) into %ir.addr) $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-store-truncating-float.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-store-truncating-float.mir index 5953e5773bfa3..267157d04fa1f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-store-truncating-float.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-store-truncating-float.mir @@ -48,11 +48,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]].ssub - ; CHECK-NEXT: STRSui [[COPY1]], %stack.0.alloca, 0 :: (store (s32) into %ir.alloca) + ; CHECK-NEXT: STRSui [[COPY1]], %stack.0.alloca, 0 :: (store (i32) into %ir.alloca) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %1:gpr(p0) = G_FRAME_INDEX %stack.0.alloca - G_STORE %0(s64), %1(p0) :: (store (s32) into %ir.alloca) + G_STORE %0(i64), %1(p0) :: (store (i32) into %ir.alloca) RET_ReallyLR ... @@ -78,11 +78,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY [[COPY]].hsub - ; CHECK-NEXT: STRHui [[COPY1]], %stack.0.alloca, 0 :: (store (s16) into %ir.alloca) + ; CHECK-NEXT: STRHui [[COPY1]], %stack.0.alloca, 0 :: (store (i16) into %ir.alloca) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %1:gpr(p0) = G_FRAME_INDEX %stack.0.alloca - G_STORE %0(s64), %1(p0) :: (store (s16) into %ir.alloca) + G_STORE %0(i64), %1(p0) :: (store (i16) into %ir.alloca) RET_ReallyLR ... @@ -108,11 +108,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr8 = COPY [[COPY]].bsub - ; CHECK-NEXT: STRBui [[COPY1]], %stack.0.alloca, 0 :: (store (s8) into %ir.alloca) + ; CHECK-NEXT: STRBui [[COPY1]], %stack.0.alloca, 0 :: (store (i8) into %ir.alloca) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %1:gpr(p0) = G_FRAME_INDEX %stack.0.alloca - G_STORE %0(s64), %1(p0) :: (store (s8) into %ir.alloca) + G_STORE %0(i64), %1(p0) :: (store (i8) into %ir.alloca) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir index ade4322f5d87e..3cc6ef4d4cb0b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir @@ -65,10 +65,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK-NEXT: STRXui [[COPY1]], [[COPY]], 0 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRXui [[COPY1]], [[COPY]], 0 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = COPY $x1 - G_STORE %1, %0 :: (store (s64) into %ir.addr) + %1(i64) = COPY $x1 + G_STORE %1, %0 :: (store (i64) into %ir.addr) ... @@ -90,10 +90,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRWui [[COPY1]], [[COPY]], 0 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRWui [[COPY1]], [[COPY]], 0 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = COPY $w1 - G_STORE %1, %0 :: (store (s32) into %ir.addr) + %1(i32) = COPY $w1 + G_STORE %1, %0 :: (store (i32) into %ir.addr) ... @@ -115,11 +115,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 0 :: (store (s16) into %ir.addr) + ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 0 :: (store (i16) into %ir.addr) %0(p0) = COPY $x0 - %2:gpr(s32) = COPY $w1 - %1(s16) = G_TRUNC %2 - G_STORE %1, %0 :: (store (s16) into %ir.addr) + %2:gpr(i32) = COPY $w1 + %1(i16) = G_TRUNC %2 + G_STORE %1, %0 :: (store (i16) into %ir.addr) ... @@ -141,11 +141,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRBBui [[COPY1]], [[COPY]], 0 :: (store (s8) into %ir.addr) + ; CHECK-NEXT: STRBBui [[COPY1]], [[COPY]], 0 :: (store (i8) into %ir.addr) %0(p0) = COPY $x0 - %2:gpr(s32) = COPY $w1 - %1(s8) = G_TRUNC %2 - G_STORE %1, %0 :: (store (s8) into %ir.addr) + %2:gpr(i32) = COPY $w1 + %1(i8) = G_TRUNC %2 + G_STORE %1, %0 :: (store (i8) into %ir.addr) ... @@ -166,10 +166,10 @@ body: | ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 0 - G_STORE %1, %0 :: (store (s64) into %ir.addr) + %1(i64) = G_CONSTANT i64 0 + G_STORE %1, %0 :: (store (i64) into %ir.addr) ... @@ -190,10 +190,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRWui $wzr, [[COPY]], 0 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRWui $wzr, [[COPY]], 0 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = G_CONSTANT i32 0 - G_STORE %1, %0 :: (store (s32) into %ir.addr) + %1(i32) = G_CONSTANT i32 0 + G_STORE %1, %0 :: (store (i32) into %ir.addr) ... @@ -208,10 +208,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRHHui $wzr, [[COPY]], 0 :: (store (s16)) + ; CHECK-NEXT: STRHHui $wzr, [[COPY]], 0 :: (store (i16)) %0:gpr(p0) = COPY $x0 - %1:gpr(s16) = G_CONSTANT i16 0 - G_STORE %1(s16), %0(p0) :: (store (s16)) + %1:gpr(i16) = G_CONSTANT i16 0 + G_STORE %1(i16), %0(p0) :: (store (i16)) ... @@ -226,10 +226,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRBBui $wzr, [[COPY]], 0 :: (store (s8)) + ; CHECK-NEXT: STRBBui $wzr, [[COPY]], 0 :: (store (i8)) %0:gpr(p0) = COPY $x0 - %1:gpr(s8) = G_CONSTANT i8 0 - G_STORE %1(s8), %0(p0) :: (store (s8)) + %1:gpr(i8) = G_CONSTANT i8 0 + G_STORE %1(i8), %0(p0) :: (store (i8)) ... --- @@ -243,11 +243,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (i64) into %ir.addr) %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s64) = G_ZEXT %1 - G_STORE %2, %0 :: (store (s64) into %ir.addr) + %1:gpr(i32) = G_CONSTANT i32 0 + %2:gpr(i64) = G_ZEXT %1 + G_STORE %2, %0 :: (store (i64) into %ir.addr) ... --- @@ -297,12 +297,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK-NEXT: STRXui [[COPY1]], [[COPY]], 16 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRXui [[COPY1]], [[COPY]], 16 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = COPY $x1 - %2(s64) = G_CONSTANT i64 128 + %1(i64) = COPY $x1 + %2(i64) = G_CONSTANT i64 128 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s64) into %ir.addr) + G_STORE %1, %3 :: (store (i64) into %ir.addr) ... --- @@ -325,12 +325,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRWui [[COPY1]], [[COPY]], 128 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRWui [[COPY1]], [[COPY]], 128 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = COPY $w1 - %2(s64) = G_CONSTANT i64 512 + %1(i32) = COPY $w1 + %2(i64) = G_CONSTANT i64 512 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s32) into %ir.addr) + G_STORE %1, %3 :: (store (i32) into %ir.addr) ... --- @@ -353,13 +353,13 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 32 :: (store (s16) into %ir.addr) + ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 32 :: (store (i16) into %ir.addr) %0(p0) = COPY $x0 - %4:gpr(s32) = COPY $w1 - %1(s16) = G_TRUNC %4 - %2(s64) = G_CONSTANT i64 64 + %4:gpr(i32) = COPY $w1 + %1(i16) = G_TRUNC %4 + %2(i64) = G_CONSTANT i64 64 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s16) into %ir.addr) + G_STORE %1, %3 :: (store (i16) into %ir.addr) ... --- @@ -382,13 +382,13 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRBBui [[COPY1]], [[COPY]], 1 :: (store (s8) into %ir.addr) + ; CHECK-NEXT: STRBBui [[COPY1]], [[COPY]], 1 :: (store (i8) into %ir.addr) %0(p0) = COPY $x0 - %4:gpr(s32) = COPY $w1 - %1(s8) = G_TRUNC %4 - %2(s64) = G_CONSTANT i64 1 + %4:gpr(i32) = COPY $w1 + %1(i8) = G_TRUNC %4 + %2(i64) = G_CONSTANT i64 1 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s8) into %ir.addr) + G_STORE %1, %3 :: (store (i8) into %ir.addr) ... --- @@ -409,10 +409,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d1 - ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 0 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 0 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = COPY $d1 - G_STORE %1, %0 :: (store (s64) into %ir.addr) + %1(i64) = COPY $d1 + G_STORE %1, %0 :: (store (i64) into %ir.addr) ... @@ -434,10 +434,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $s1 - ; CHECK-NEXT: STRSui [[COPY1]], [[COPY]], 0 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRSui [[COPY1]], [[COPY]], 0 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = COPY $s1 - G_STORE %1, %0 :: (store (s32) into %ir.addr) + %1(i32) = COPY $s1 + G_STORE %1, %0 :: (store (i32) into %ir.addr) ... @@ -461,12 +461,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d1 - ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 1 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 1 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = COPY $d1 - %2(s64) = G_CONSTANT i64 8 + %1(i64) = COPY $d1 + %2(i64) = G_CONSTANT i64 8 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s64) into %ir.addr) + G_STORE %1, %3 :: (store (i64) into %ir.addr) ... --- @@ -489,12 +489,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $s1 - ; CHECK-NEXT: STRSui [[COPY1]], [[COPY]], 2 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRSui [[COPY1]], [[COPY]], 2 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = COPY $s1 - %2(s64) = G_CONSTANT i64 8 + %1(i32) = COPY $s1 + %2(i64) = G_CONSTANT i64 8 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s32) into %ir.addr) + G_STORE %1, %3 :: (store (i32) into %ir.addr) ... --- name: store_v2s32 @@ -514,10 +514,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d1 - ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 0 :: (store (<2 x s32>) into %ir.addr) + ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 0 :: (store (<2 x i32>) into %ir.addr) %0(p0) = COPY $x0 - %1(<2 x s32>) = COPY $d1 - G_STORE %1, %0 :: (store (<2 x s32>) into %ir.addr) + %1(<2 x i32>) = COPY $d1 + G_STORE %1, %0 :: (store (<2 x i32>) into %ir.addr) ... --- @@ -537,10 +537,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr128 = COPY $q1 - ; CHECK-NEXT: STRQui [[COPY1]], [[COPY]], 0 :: (store (<2 x s64>) into %ir.addr, align 8) + ; CHECK-NEXT: STRQui [[COPY1]], [[COPY]], 0 :: (store (<2 x i64>) into %ir.addr, align 8) %0(p0) = COPY $x0 - %1(<2 x s64>) = COPY $q1 - G_STORE %1, %0 :: (store (<2 x s64>) into %ir.addr, align 8) + %1(<2 x i64>) = COPY $q1 + G_STORE %1, %0 :: (store (<2 x i64>) into %ir.addr, align 8) ... --- @@ -562,11 +562,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRDui [[COPY]], [[COPY1]], 0 :: (store (<4 x s16>) into %ir.ptr) + ; CHECK-NEXT: STRDui [[COPY]], [[COPY1]], 0 :: (store (<4 x i16>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(<4 x s16>) = COPY $d0 + %0:fpr(<4 x i16>) = COPY $d0 %1:gpr(p0) = COPY $x0 - G_STORE %0(<4 x s16>), %1(p0) :: (store (<4 x s16>) into %ir.ptr) + G_STORE %0(<4 x i16>), %1(p0) :: (store (<4 x i16>) into %ir.ptr) RET_ReallyLR ... @@ -589,11 +589,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<4 x s32>) into %ir.ptr) + ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<4 x i32>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(<4 x s32>) = COPY $q0 + %0:fpr(<4 x i32>) = COPY $q0 %1:gpr(p0) = COPY $x0 - G_STORE %0(<4 x s32>), %1(p0) :: (store (<4 x s32>) into %ir.ptr) + G_STORE %0(<4 x i32>), %1(p0) :: (store (<4 x i32>) into %ir.ptr) RET_ReallyLR ... @@ -616,11 +616,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<8 x s16>) into %ir.ptr) + ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<8 x i16>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(<8 x s16>) = COPY $q0 + %0:fpr(<8 x i16>) = COPY $q0 %1:gpr(p0) = COPY $x0 - G_STORE %0(<8 x s16>), %1(p0) :: (store (<8 x s16>) into %ir.ptr) + G_STORE %0(<8 x i16>), %1(p0) :: (store (<8 x i16>) into %ir.ptr) RET_ReallyLR ... @@ -643,11 +643,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<16 x s8>) into %ir.ptr) + ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<16 x i8>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(<16 x s8>) = COPY $q0 + %0:fpr(<16 x i8>) = COPY $q0 %1:gpr(p0) = COPY $x0 - G_STORE %0(<16 x s8>), %1(p0) :: (store (<16 x s8>) into %ir.ptr) + G_STORE %0(<16 x i8>), %1(p0) :: (store (<16 x i8>) into %ir.ptr) RET_ReallyLR ... @@ -728,36 +728,36 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: %val32:gpr32 = COPY $w1 ; CHECK-NEXT: %val64:gpr64 = COPY $x2 - ; CHECK-NEXT: STRBBui %val32, [[COPY]], 0 :: (store (s8)) - ; CHECK-NEXT: STRBBui %val32, [[COPY]], 43 :: (store (s8)) - ; CHECK-NEXT: STRHHui %val32, [[COPY]], 0 :: (store (s16)) - ; CHECK-NEXT: STURHHi %val32, [[COPY]], 43 :: (store (s16)) + ; CHECK-NEXT: STRBBui %val32, [[COPY]], 0 :: (store (i8)) + ; CHECK-NEXT: STRBBui %val32, [[COPY]], 43 :: (store (i8)) + ; CHECK-NEXT: STRHHui %val32, [[COPY]], 0 :: (store (i16)) + ; CHECK-NEXT: STURHHi %val32, [[COPY]], 43 :: (store (i16)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY %val64.sub_32 - ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 0 :: (store (s16)) + ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 0 :: (store (i16)) ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY %val64.sub_32 - ; CHECK-NEXT: STURHHi [[COPY2]], [[COPY]], 43 :: (store (s16)) + ; CHECK-NEXT: STURHHi [[COPY2]], [[COPY]], 43 :: (store (i16)) ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr32 = COPY %val64.sub_32 - ; CHECK-NEXT: STRWui [[COPY3]], [[COPY]], 0 :: (store (s32)) + ; CHECK-NEXT: STRWui [[COPY3]], [[COPY]], 0 :: (store (i32)) ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gpr32 = COPY %val64.sub_32 - ; CHECK-NEXT: STURWi [[COPY4]], [[COPY]], 43 :: (store (s32)) + ; CHECK-NEXT: STURWi [[COPY4]], [[COPY]], 43 :: (store (i32)) %0:gpr(p0) = COPY $x0 - %val32:gpr(s32) = COPY $w1 - %val64:gpr(s64) = COPY $x2 - G_STORE %val32, %0 :: (store (s8)) + %val32:gpr(i32) = COPY $w1 + %val64:gpr(i64) = COPY $x2 + G_STORE %val32, %0 :: (store (i8)) ; unscaled offset: - %cst:gpr(s64) = G_CONSTANT i64 43 + %cst:gpr(i64) = G_CONSTANT i64 43 %newptr:gpr(p0) = G_PTR_ADD %0, %cst - G_STORE %val32, %newptr :: (store (s8)) + G_STORE %val32, %newptr :: (store (i8)) - G_STORE %val32, %0 :: (store (s16)) + G_STORE %val32, %0 :: (store (i16)) ; unscaled offset: - G_STORE %val32, %newptr :: (store (s16)) + G_STORE %val32, %newptr :: (store (i16)) - G_STORE %val64, %0 :: (store (s16)) + G_STORE %val64, %0 :: (store (i16)) ; unscaled offset: - G_STORE %val64, %newptr :: (store (s16)) + G_STORE %val64, %newptr :: (store (i16)) - G_STORE %val64, %0 :: (store (s32)) + G_STORE %val64, %0 :: (store (i32)) ; unscaled offset: - G_STORE %val64, %newptr :: (store (s32)) + G_STORE %val64, %newptr :: (store (i32)) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-stx.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-stx.mir index 3cc916e020095..f293c72b763d8 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-stx.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-stx.mir @@ -26,7 +26,7 @@ body: | ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[INSERT_SUBREG]].sub_32 - ; CHECK-NEXT: early-clobber %5:gpr32 = STXRB [[COPY2]], [[COPY1]] :: (volatile store (s8) into %ir.addr) + ; CHECK-NEXT: early-clobber %5:gpr32 = STXRB [[COPY2]], [[COPY1]] :: (volatile store (i8) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %5 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %3:gpr(i32) = COPY $w1 @@ -34,7 +34,7 @@ body: | %6:gpr(i64) = G_CONSTANT i64 255 %7:gpr(i64) = G_ANYEXT %3(i32) %4:gpr(i64) = G_AND %7, %6 - %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %4(i64), %2(p0) :: (volatile store (s8) into %ir.addr) + %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %4(i64), %2(p0) :: (volatile store (i8) into %ir.addr) $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 @@ -58,7 +58,7 @@ body: | ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[INSERT_SUBREG]].sub_32 - ; CHECK-NEXT: early-clobber %5:gpr32 = STXRH [[COPY2]], [[COPY1]] :: (volatile store (s16) into %ir.addr) + ; CHECK-NEXT: early-clobber %5:gpr32 = STXRH [[COPY2]], [[COPY1]] :: (volatile store (i16) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %5 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %3:gpr(i32) = COPY $w1 @@ -66,7 +66,7 @@ body: | %6:gpr(i64) = G_CONSTANT i64 65535 %7:gpr(i64) = G_ANYEXT %3(i32) %4:gpr(i64) = G_AND %7, %6 - %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %4(i64), %2(p0) :: (volatile store (s16) into %ir.addr) + %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %4(i64), %2(p0) :: (volatile store (i16) into %ir.addr) $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 @@ -87,13 +87,13 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x2 - ; CHECK-NEXT: early-clobber %3:gpr32 = STXRW [[COPY]], [[COPY1]] :: (volatile store (s32) into %ir.addr) + ; CHECK-NEXT: early-clobber %3:gpr32 = STXRW [[COPY]], [[COPY1]] :: (volatile store (i32) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(i32) = COPY $w1 %2:gpr(p0) = COPY $x2 %3:gpr(i64) = G_ZEXT %1(i32) - %4:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %3(i64), %2(p0) :: (volatile store (s32) into %ir.addr) + %4:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %3(i64), %2(p0) :: (volatile store (i32) into %ir.addr) $w0 = COPY %4(i32) RET_ReallyLR implicit $w0 @@ -114,12 +114,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x2 - ; CHECK-NEXT: early-clobber %2:gpr32 = STXRX [[COPY]], [[COPY1]] :: (volatile store (s64) into %ir.addr) + ; CHECK-NEXT: early-clobber %2:gpr32 = STXRX [[COPY]], [[COPY1]] :: (volatile store (i64) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %2 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(i64) = COPY $x1 %2:gpr(p0) = COPY $x2 - %3:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %1(i64), %2(p0) :: (volatile store (s64) into %ir.addr) + %3:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %1(i64), %2(p0) :: (volatile store (i64) into %ir.addr) $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir index 67262c27e2059..c13d607a4bcdd 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir @@ -27,9 +27,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s64) = COPY $x0 - %zero:gpr(s64) = G_CONSTANT i64 0 - %cmp:gpr(s32) = G_ICMP intpred(slt), %copy(s64), %zero + %copy:gpr(i64) = COPY $x0 + %zero:gpr(i64) = G_CONSTANT i64 0 + %cmp:gpr(i32) = G_ICMP intpred(slt), %copy(i64), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -56,9 +56,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s32) = COPY $w0 - %zero:gpr(s32) = G_CONSTANT i32 0 - %cmp:gpr(s32) = G_ICMP intpred(slt), %copy(s32), %zero + %copy:gpr(i32) = COPY $w0 + %zero:gpr(i32) = G_CONSTANT i32 0 + %cmp:gpr(i32) = G_ICMP intpred(slt), %copy(i32), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -85,9 +85,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s64) = COPY $x0 - %zero:gpr(s64) = G_CONSTANT i64 0 - %cmp:gpr(s32) = G_ICMP intpred(sge), %copy(s64), %zero + %copy:gpr(i64) = COPY $x0 + %zero:gpr(i64) = G_CONSTANT i64 0 + %cmp:gpr(i32) = G_ICMP intpred(sge), %copy(i64), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -114,9 +114,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s32) = COPY $w0 - %zero:gpr(s32) = G_CONSTANT i32 0 - %cmp:gpr(s32) = G_ICMP intpred(sge), %copy(s32), %zero + %copy:gpr(i32) = COPY $w0 + %zero:gpr(i32) = G_CONSTANT i32 0 + %cmp:gpr(i32) = G_ICMP intpred(sge), %copy(i32), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -144,9 +144,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s32) = COPY $w0 - %one:gpr(s32) = G_CONSTANT i32 1 - %cmp:gpr(s32) = G_ICMP intpred(slt), %copy(s32), %one + %copy:gpr(i32) = COPY $w0 + %one:gpr(i32) = G_CONSTANT i32 1 + %cmp:gpr(i32) = G_ICMP intpred(slt), %copy(i32), %one G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -174,12 +174,12 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s64) = COPY $x0 - %bit:gpr(s64) = G_CONSTANT i64 8 - %zero:gpr(s64) = G_CONSTANT i64 0 - %c:gpr(s64) = G_CONSTANT i64 8 - %and:gpr(s64) = G_AND %copy, %bit - %cmp:gpr(s32) = G_ICMP intpred(slt), %and(s64), %zero + %copy:gpr(i64) = COPY $x0 + %bit:gpr(i64) = G_CONSTANT i64 8 + %zero:gpr(i64) = G_CONSTANT i64 0 + %c:gpr(i64) = G_CONSTANT i64 8 + %and:gpr(i64) = G_AND %copy, %bit + %cmp:gpr(i32) = G_ICMP intpred(slt), %and(i64), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -208,9 +208,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s64) = COPY $x0 - %zero:gpr(s64) = G_CONSTANT i64 0 - %cmp:gpr(s32) = G_ICMP intpred(slt), %zero, %copy(s64) + %copy:gpr(i64) = COPY $x0 + %zero:gpr(i64) = G_CONSTANT i64 0 + %cmp:gpr(i32) = G_ICMP intpred(slt), %zero, %copy(i64) G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-trn.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-trn.mir index 816eaf53e0d89..44395c0da7804 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-trn.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-trn.mir @@ -23,10 +23,10 @@ body: | ; CHECK-NEXT: [[TRN1v2i32_:%[0-9]+]]:fpr64 = TRN1v2i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN1v2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_TRN1 %0, %1 - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_TRN1 %0, %1 + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -47,10 +47,10 @@ body: | ; CHECK-NEXT: [[TRN1v2i64_:%[0-9]+]]:fpr128 = TRN1v2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN1v2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_TRN1 %0, %1 - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_TRN1 %0, %1 + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -71,10 +71,10 @@ body: | ; CHECK-NEXT: [[TRN1v4i16_:%[0-9]+]]:fpr64 = TRN1v4i16 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN1v4i16_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<4 x s16>) = COPY $d1 - %2:fpr(<4 x s16>) = G_TRN1 %0, %1 - $d0 = COPY %2(<4 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<4 x i16>) = COPY $d1 + %2:fpr(<4 x i16>) = G_TRN1 %0, %1 + $d0 = COPY %2(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -95,10 +95,10 @@ body: | ; CHECK-NEXT: [[TRN1v4i32_:%[0-9]+]]:fpr128 = TRN1v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN1v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_TRN1 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_TRN1 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -119,10 +119,10 @@ body: | ; CHECK-NEXT: [[TRN1v8i8_:%[0-9]+]]:fpr64 = TRN1v8i8 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN1v8i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<8 x s8>) = COPY $d0 - %1:fpr(<8 x s8>) = COPY $d1 - %2:fpr(<8 x s8>) = G_TRN1 %0, %1 - $d0 = COPY %2(<8 x s8>) + %0:fpr(<8 x i8>) = COPY $d0 + %1:fpr(<8 x i8>) = COPY $d1 + %2:fpr(<8 x i8>) = G_TRN1 %0, %1 + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -143,10 +143,10 @@ body: | ; CHECK-NEXT: [[TRN1v8i16_:%[0-9]+]]:fpr128 = TRN1v8i16 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN1v8i16_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:fpr(<8 x s16>) = COPY $q1 - %2:fpr(<8 x s16>) = G_TRN1 %0, %1 - $q0 = COPY %2(<8 x s16>) + %0:fpr(<8 x i16>) = COPY $q0 + %1:fpr(<8 x i16>) = COPY $q1 + %2:fpr(<8 x i16>) = G_TRN1 %0, %1 + $q0 = COPY %2(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -167,10 +167,10 @@ body: | ; CHECK-NEXT: [[TRN1v16i8_:%[0-9]+]]:fpr128 = TRN1v16i8 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN1v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<16 x s8>) = COPY $q0 - %1:fpr(<16 x s8>) = COPY $q1 - %2:fpr(<16 x s8>) = G_TRN1 %0, %1 - $q0 = COPY %2(<16 x s8>) + %0:fpr(<16 x i8>) = COPY $q0 + %1:fpr(<16 x i8>) = COPY $q1 + %2:fpr(<16 x i8>) = G_TRN1 %0, %1 + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -191,10 +191,10 @@ body: | ; CHECK-NEXT: [[TRN2v2i32_:%[0-9]+]]:fpr64 = TRN2v2i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN2v2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_TRN2 %0, %1 - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_TRN2 %0, %1 + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -215,10 +215,10 @@ body: | ; CHECK-NEXT: [[TRN2v2i64_:%[0-9]+]]:fpr128 = TRN2v2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN2v2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_TRN2 %0, %1 - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_TRN2 %0, %1 + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -239,10 +239,10 @@ body: | ; CHECK-NEXT: [[TRN2v4i16_:%[0-9]+]]:fpr64 = TRN2v4i16 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN2v4i16_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<4 x s16>) = COPY $d1 - %2:fpr(<4 x s16>) = G_TRN2 %0, %1 - $d0 = COPY %2(<4 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<4 x i16>) = COPY $d1 + %2:fpr(<4 x i16>) = G_TRN2 %0, %1 + $d0 = COPY %2(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -263,10 +263,10 @@ body: | ; CHECK-NEXT: [[TRN2v4i32_:%[0-9]+]]:fpr128 = TRN2v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN2v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_TRN2 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_TRN2 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -287,10 +287,10 @@ body: | ; CHECK-NEXT: [[TRN2v8i8_:%[0-9]+]]:fpr64 = TRN2v8i8 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN2v8i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<8 x s8>) = COPY $d0 - %1:fpr(<8 x s8>) = COPY $d1 - %2:fpr(<8 x s8>) = G_TRN2 %0, %1 - $d0 = COPY %2(<8 x s8>) + %0:fpr(<8 x i8>) = COPY $d0 + %1:fpr(<8 x i8>) = COPY $d1 + %2:fpr(<8 x i8>) = G_TRN2 %0, %1 + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -311,10 +311,10 @@ body: | ; CHECK-NEXT: [[TRN2v8i16_:%[0-9]+]]:fpr128 = TRN2v8i16 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN2v8i16_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:fpr(<8 x s16>) = COPY $q1 - %2:fpr(<8 x s16>) = G_TRN2 %0, %1 - $q0 = COPY %2(<8 x s16>) + %0:fpr(<8 x i16>) = COPY $q0 + %1:fpr(<8 x i16>) = COPY $q1 + %2:fpr(<8 x i16>) = G_TRN2 %0, %1 + $q0 = COPY %2(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -335,8 +335,8 @@ body: | ; CHECK-NEXT: [[TRN2v16i8_:%[0-9]+]]:fpr128 = TRN2v16i8 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN2v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<16 x s8>) = COPY $q0 - %1:fpr(<16 x s8>) = COPY $q1 - %2:fpr(<16 x s8>) = G_TRN2 %0, %1 - $q0 = COPY %2(<16 x s8>) + %0:fpr(<16 x i8>) = COPY $q0 + %1:fpr(<16 x i8>) = COPY $q1 + %2:fpr(<16 x i8>) = G_TRN2 %0, %1 + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-trunc.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-trunc.mir index c0b936332ca88..43b92865f0572 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-trunc.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-trunc.mir @@ -104,7 +104,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[COPY]].dsub ; CHECK-NEXT: $x0 = COPY [[COPY1]] - %0(s128) = COPY $q0 + %0(i128) = COPY $q0 %1(i64) = G_TRUNC %0 $x0 = COPY %1(i64) ... @@ -127,7 +127,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]].ssub ; CHECK-NEXT: $w0 = COPY [[COPY1]] - %0(s128) = COPY $q0 + %0(i128) = COPY $q0 %1(i32) = G_TRUNC %0 $w0 = COPY %1(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-truncstore-atomic.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-truncstore-atomic.mir index 33c56c4a6d044..287b82f9c8c5c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-truncstore-atomic.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-truncstore-atomic.mir @@ -27,7 +27,7 @@ body: | ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 4 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[SUBREG_TO_REG]].sub_32 - ; CHECK-NEXT: STLRW [[COPY2]], [[COPY]] :: (store release (s32)) + ; CHECK-NEXT: STLRW [[COPY2]], [[COPY]] :: (store release (i32)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -35,13 +35,13 @@ body: | liveins: $w1, $x0 %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = COPY $w1 + %3:gpr(i32) = COPY $w1 G_BRCOND %3, %bb.3 G_BR %bb.2 bb.2: - %8:gpr(s64) = G_CONSTANT i64 4 - G_STORE %8(s64), %0(p0) :: (store release (s32)) + %8:gpr(i64) = G_CONSTANT i64 4 + G_STORE %8(i64), %0(p0) :: (store release (i32)) bb.3: RET_ReallyLR @@ -73,7 +73,7 @@ body: | ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 4 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[SUBREG_TO_REG]].sub_32 - ; CHECK-NEXT: STLRH [[COPY2]], [[COPY]] :: (store release (s16)) + ; CHECK-NEXT: STLRH [[COPY2]], [[COPY]] :: (store release (i16)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -81,13 +81,13 @@ body: | liveins: $w1, $x0 %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = COPY $w1 + %3:gpr(i32) = COPY $w1 G_BRCOND %3, %bb.3 G_BR %bb.2 bb.2: - %8:gpr(s64) = G_CONSTANT i64 4 - G_STORE %8(s64), %0(p0) :: (store release (s16)) + %8:gpr(i64) = G_CONSTANT i64 4 + G_STORE %8(i64), %0(p0) :: (store release (i16)) bb.3: RET_ReallyLR @@ -119,7 +119,7 @@ body: | ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 4 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[SUBREG_TO_REG]].sub_32 - ; CHECK-NEXT: STLRB [[COPY2]], [[COPY]] :: (store release (s8)) + ; CHECK-NEXT: STLRB [[COPY2]], [[COPY]] :: (store release (i8)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -127,13 +127,13 @@ body: | liveins: $w1, $x0 %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = COPY $w1 + %3:gpr(i32) = COPY $w1 G_BRCOND %3, %bb.3 G_BR %bb.2 bb.2: - %8:gpr(s64) = G_CONSTANT i64 4 - G_STORE %8(s64), %0(p0) :: (store release (s8)) + %8:gpr(i64) = G_CONSTANT i64 4 + G_STORE %8(i64), %0(p0) :: (store release (i8)) bb.3: RET_ReallyLR diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-uadde.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-uadde.mir index f6f9964e6babd..7cd67b2e338f6 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-uadde.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-uadde.mir @@ -23,12 +23,12 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADCSXr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s64), %4:gpr(s32) = G_UADDE %0, %1, %2 - $x0 = COPY %3(s64) - $w1 = COPY %4(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i64), %4:gpr(i32) = G_UADDE %0, %1, %2 + $x0 = COPY %3(i64) + $w1 = COPY %4(i32) RET_ReallyLR implicit $x0, implicit $w1 ... ... @@ -54,12 +54,12 @@ body: | ; CHECK-NEXT: $w0 = COPY [[ADCSWr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32), %4:gpr(s32) = G_UADDE %0, %1, %2 - $w0 = COPY %3(s32) - $w1 = COPY %4(s32) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32), %4:gpr(i32) = G_UADDE %0, %1, %2 + $w0 = COPY %3(i32) + $w1 = COPY %4(i32) RET_ReallyLR implicit $w0, implicit $w1 ... ... @@ -85,14 +85,14 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADDSXrr]] ; CHECK-NEXT: $x1 = COPY [[ADCSXr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %8:gpr(s64), %12:gpr(s32) = G_UADDO %0, %2 - %9:gpr(s64), %13:gpr(s32) = G_UADDE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %8:gpr(i64), %12:gpr(i32) = G_UADDO %0, %2 + %9:gpr(i64), %13:gpr(i32) = G_UADDE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -120,15 +120,15 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADCSXr]] ; CHECK-NEXT: $x1 = COPY [[ADCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %6:gpr(s32) = G_CONSTANT i32 1 - %8:gpr(s64), %12:gpr(s32) = G_UADDE %0, %2, %6 - %9:gpr(s64), %13:gpr(s32) = G_UADDE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %6:gpr(i32) = G_CONSTANT i32 1 + %8:gpr(i64), %12:gpr(i32) = G_UADDE %0, %2, %6 + %9:gpr(i64), %13:gpr(i32) = G_UADDE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -160,19 +160,19 @@ body: | ; CHECK-NEXT: $x1 = COPY [[ADCSXr]] ; CHECK-NEXT: $x2 = COPY [[ADCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %4:gpr(s64) = COPY $x4 - %5:gpr(s64) = COPY $x5 - %6:gpr(s64) = COPY $x6 - %7:gpr(s64), %11:gpr(s32) = G_UADDO %0, %4 - %8:gpr(s64), %12:gpr(s32) = G_UADDE %1, %5, %11 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %4:gpr(i64) = COPY $x4 + %5:gpr(i64) = COPY $x5 + %6:gpr(i64) = COPY $x6 + %7:gpr(i64), %11:gpr(i32) = G_UADDO %0, %4 + %8:gpr(i64), %12:gpr(i32) = G_UADDE %1, %5, %11 ; carry-in is not produced by previous instruction - %9:gpr(s64), %13:gpr(s32) = G_UADDE %2, %6, %11 - $x0 = COPY %7(s64) - $x1 = COPY %8(s64) - $x2 = COPY %9(s64) + %9:gpr(i64), %13:gpr(i32) = G_UADDE %2, %6, %11 + $x0 = COPY %7(i64) + $x1 = COPY %8(i64) + $x2 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 ... ... @@ -197,12 +197,12 @@ body: | ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 3, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %4:gpr(s64), %5:gpr(s32) = G_UADDO %0, %2 - %6:gpr(s64), %7:gpr(s32) = G_UADDE %1, %3, %5 - $w0 = COPY %7(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %4:gpr(i64), %5:gpr(i32) = G_UADDO %0, %2 + %6:gpr(i64), %7:gpr(i32) = G_UADDE %1, %3, %5 + $w0 = COPY %7(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-uaddo.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-uaddo.mir index 9dcd085fc4fd5..d829f7092b07b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-uaddo.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-uaddo.mir @@ -22,9 +22,9 @@ body: | ; CHECK-NEXT: $w0 = COPY [[ADDSWrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %3:gpr(s32), %4:gpr(s32) = G_UADDO %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %3:gpr(i32), %4:gpr(i32) = G_UADDO %0, %1 $w0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $w0, implicit $w1 @@ -50,9 +50,9 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADDSXrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %3:gpr(s64), %4:gpr(s32) = G_UADDO %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %3:gpr(i64), %4:gpr(i32) = G_UADDO %0, %1 $x0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $x0, implicit $w1 @@ -75,10 +75,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 16 - %add:gpr(s32), %overflow:gpr(s32) = G_UADDO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 16 + %add:gpr(i32), %overflow:gpr(i32) = G_UADDO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -100,12 +100,12 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWrs %copy1, %copy2, 16, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy1:gpr(s32) = COPY $w0 - %copy2:gpr(s32) = COPY $w1 - %constant:gpr(s32) = G_CONSTANT i32 16 - %shift:gpr(s32) = G_SHL %copy2(s32), %constant(s32) - %add:gpr(s32), %overflow:gpr(s32) = G_UADDO %copy1, %shift - $w0 = COPY %add(s32) + %copy1:gpr(i32) = COPY $w0 + %copy2:gpr(i32) = COPY $w1 + %constant:gpr(i32) = G_CONSTANT i32 16 + %shift:gpr(i32) = G_SHL %copy2(i32), %constant(i32) + %add:gpr(i32), %overflow:gpr(i32) = G_UADDO %copy1, %shift + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -126,10 +126,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 -16 - %add:gpr(s32), %overflow:gpr(s32) = G_UADDO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 -16 + %add:gpr(i32), %overflow:gpr(i32) = G_UADDO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -151,11 +151,11 @@ body: | ; CHECK-NEXT: %add:gpr64 = ADDSXrx %reg0, %reg1, 18, implicit-def $nzcv ; CHECK-NEXT: $x0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:gpr(s64) = COPY $x0 - %reg1:gpr(s32) = COPY $w0 - %ext:gpr(s64) = G_ZEXT %reg1(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %add:gpr(s64), %flags:gpr(s32) = G_UADDO %reg0, %shift - $x0 = COPY %add(s64) + %reg0:gpr(i64) = COPY $x0 + %reg1:gpr(i32) = COPY $w0 + %ext:gpr(i64) = G_ZEXT %reg1(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %add:gpr(i64), %flags:gpr(i32) = G_UADDO %reg0, %shift + $x0 = COPY %add(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir index c15b668c5aa76..8a10c8dbbdc0a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir @@ -16,10 +16,10 @@ body: | ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 0, 9 ; CHECK: $w0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 0 - %cst2:gpr(s32) = G_CONSTANT i32 10 - %ubfx:gpr(s32) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 0 + %cst2:gpr(i32) = G_CONSTANT i32 10 + %ubfx:gpr(i32) = G_UBFX %copy, %cst1, %cst2 $w0 = COPY %ubfx RET_ReallyLR implicit $w0 @@ -38,10 +38,10 @@ body: | ; CHECK: %ubfx:gpr64 = UBFMXri %copy, 0, 9 ; CHECK: $x0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $x0 - %copy:gpr(s64) = COPY $x0 - %cst1:gpr(s64) = G_CONSTANT i64 0 - %cst2:gpr(s64) = G_CONSTANT i64 10 - %ubfx:gpr(s64) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i64) = COPY $x0 + %cst1:gpr(i64) = G_CONSTANT i64 0 + %cst2:gpr(i64) = G_CONSTANT i64 10 + %ubfx:gpr(i64) = G_UBFX %copy, %cst1, %cst2 $x0 = COPY %ubfx RET_ReallyLR implicit $x0 @@ -63,10 +63,10 @@ body: | ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 31, 31 ; CHECK: $w0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 31 - %cst2:gpr(s32) = G_CONSTANT i32 1 - %ubfx:gpr(s32) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 31 + %cst2:gpr(i32) = G_CONSTANT i32 1 + %ubfx:gpr(i32) = G_UBFX %copy, %cst1, %cst2 $w0 = COPY %ubfx RET_ReallyLR implicit $w0 --- @@ -83,10 +83,10 @@ body: | ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 10, 14 ; CHECK: $w0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 10 - %cst2:gpr(s32) = G_CONSTANT i32 5 - %ubfx:gpr(s32) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 10 + %cst2:gpr(i32) = G_CONSTANT i32 5 + %ubfx:gpr(i32) = G_UBFX %copy, %cst1, %cst2 $w0 = COPY %ubfx RET_ReallyLR implicit $w0 @@ -105,9 +105,9 @@ body: | ; CHECK: %ubfx:gpr64 = UBFMXri %copy, 10, 14 ; CHECK: $x0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $x0 - %copy:gpr(s64) = COPY $x0 - %cst1:gpr(s64) = G_CONSTANT i64 10 - %cst2:gpr(s64) = G_CONSTANT i64 5 - %ubfx:gpr(s64) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i64) = COPY $x0 + %cst1:gpr(i64) = G_CONSTANT i64 10 + %cst2:gpr(i64) = G_CONSTANT i64 5 + %ubfx:gpr(i64) = G_UBFX %copy, %cst1, %cst2 $x0 = COPY %ubfx RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-unmerge.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-unmerge.mir index 8a9f2cac79e9f..da58fa4815d94 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-unmerge.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-unmerge.mir @@ -30,13 +30,13 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG]], 1, [[INSERT_SUBREG1]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 + %0:fpr(<2 x i64>) = COPY $q0 ; Since 2 * 64 = 128, we can just directly copy. - %2:fpr(s64), %3:fpr(s64) = G_UNMERGE_VALUES %0(<2 x s64>) + %2:fpr(i64), %3:fpr(i64) = G_UNMERGE_VALUES %0(<2 x i64>) - %1:fpr(<2 x s64>) = G_BUILD_VECTOR %2(s64), %3(s64) - $q0 = COPY %1(<2 x s64>) + %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(i64), %3(i64) + $q0 = COPY %1(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -76,13 +76,13 @@ body: | ; CHECK-NEXT: [[INSvi32lane2:%[0-9]+]]:fpr128 = INSvi32lane [[INSvi32lane1]], 3, [[INSERT_SUBREG3]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi32lane2]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 + %0:fpr(<4 x i32>) = COPY $q0 ; Since 4 * 32 = 128, we can just directly copy. - %2:fpr(s32), %3:fpr(s32), %4:fpr(s32), %5:fpr(s32) = G_UNMERGE_VALUES %0(<4 x s32>) + %2:fpr(i32), %3:fpr(i32), %4:fpr(i32), %5:fpr(i32) = G_UNMERGE_VALUES %0(<4 x i32>) - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %3(s32), %4(s32), %5(s32) - $q0 = COPY %1(<4 x s32>) + %1:fpr(<4 x i32>) = G_BUILD_VECTOR %2(i32), %3(i32), %4(i32), %5(i32) + $q0 = COPY %1(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -112,15 +112,15 @@ body: | ; CHECK-NEXT: $h0 = COPY [[COPY1]] ; CHECK-NEXT: $h1 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0, implicit $h1 - %0:fpr(<2 x s16>) = COPY $s0 + %0:fpr(<2 x i16>) = COPY $s0 ; Since 2 * 16 != 128, we need to widen using implicit defs. ; Note that we expect to reuse one of the INSERT_SUBREG results, as CPYi16 ; expects a lane > 0. - %2:fpr(s16), %3:fpr(s16) = G_UNMERGE_VALUES %0(<2 x s16>) + %2:fpr(i16), %3:fpr(i16) = G_UNMERGE_VALUES %0(<2 x i16>) - $h0 = COPY %2(s16) - $h1 = COPY %3(s16) + $h0 = COPY %2(i16) + $h1 = COPY %3(i16) RET_ReallyLR implicit $h0, implicit $h1 ... @@ -168,15 +168,15 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi16lane2]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s16>) = COPY $d0 + %0:fpr(<4 x i16>) = COPY $d0 ; Since 4 * 16 != 128, we need to widen using implicit defs. ; Note that we expect to reuse one of the INSERT_SUBREG results, as CPYi16 ; expects a lane > 0. - %2:fpr(s16), %3:fpr(s16), %4:fpr(s16), %5:fpr(s16) = G_UNMERGE_VALUES %0(<4 x s16>) + %2:fpr(i16), %3:fpr(i16), %4:fpr(i16), %5:fpr(i16) = G_UNMERGE_VALUES %0(<4 x i16>) - %1:fpr(<4 x s16>) = G_BUILD_VECTOR %2(s16), %3(s16), %4(s16), %5(s16) - $d0 = COPY %1(<4 x s16>) + %1:fpr(<4 x i16>) = G_BUILD_VECTOR %2(i16), %3(i16), %4(i16), %5(i16) + $d0 = COPY %1(<4 x i16>) RET_ReallyLR implicit $d0 ... --- @@ -236,13 +236,13 @@ body: | ; CHECK-NEXT: [[INSvi16lane6:%[0-9]+]]:fpr128 = INSvi16lane [[INSvi16lane5]], 7, [[INSERT_SUBREG7]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi16lane6]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<8 x s16>) = COPY $q0 + %0:fpr(<8 x i16>) = COPY $q0 ; Since 8 * 16 = 128, we can just directly copy. - %2:fpr(s16), %3:fpr(s16), %4:fpr(s16), %5:fpr(s16), %6:fpr(s16), %7:fpr(s16), %8:fpr(s16), %9:fpr(s16) = G_UNMERGE_VALUES %0(<8 x s16>) + %2:fpr(i16), %3:fpr(i16), %4:fpr(i16), %5:fpr(i16), %6:fpr(i16), %7:fpr(i16), %8:fpr(i16), %9:fpr(i16) = G_UNMERGE_VALUES %0(<8 x i16>) - %1:fpr(<8 x s16>) = G_BUILD_VECTOR %2:fpr(s16), %3:fpr(s16), %4:fpr(s16), %5:fpr(s16), %6:fpr(s16), %7:fpr(s16), %8:fpr(s16), %9:fpr(s16) - $q0 = COPY %1(<8 x s16>) + %1:fpr(<8 x i16>) = G_BUILD_VECTOR %2:fpr(i16), %3:fpr(i16), %4:fpr(i16), %5:fpr(i16), %6:fpr(i16), %7:fpr(i16), %8:fpr(i16), %9:fpr(i16) + $q0 = COPY %1(<8 x i16>) RET_ReallyLR implicit $q0 ... --- @@ -289,8 +289,8 @@ body: | ; CHECK-NEXT: $b6 = COPY [[DUPi8_5]] ; CHECK-NEXT: $b7 = COPY [[DUPi8_6]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<8 x s8>) = COPY $d0 - %2:fpr(s8), %3:fpr(s8), %4:fpr(s8), %5:fpr(s8), %6:fpr(s8), %7:fpr(s8), %8:fpr(s8), %9:fpr(s8) = G_UNMERGE_VALUES %0(<8 x s8>) + %0:fpr(<8 x i8>) = COPY $d0 + %2:fpr(i8), %3:fpr(i8), %4:fpr(i8), %5:fpr(i8), %6:fpr(i8), %7:fpr(i8), %8:fpr(i8), %9:fpr(i8) = G_UNMERGE_VALUES %0(<8 x i8>) $b0 = COPY %2 $b1 = COPY %3 $b2 = COPY %4 @@ -379,11 +379,11 @@ body: | ; CHECK-NEXT: [[INSvi8lane14:%[0-9]+]]:fpr128 = INSvi8lane [[INSvi8lane13]], 15, [[INSERT_SUBREG15]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi8lane14]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<16 x s8>) = COPY $q0 - %2:fpr(s8), %3:fpr(s8), %4:fpr(s8), %5:fpr(s8), %6:fpr(s8), %7:fpr(s8), %8:fpr(s8), %9:fpr(s8), %10:fpr(s8), %11:fpr(s8), %12:fpr(s8), %13:fpr(s8), %14:fpr(s8), %15:fpr(s8), %16:fpr(s8), %17:fpr(s8) = G_UNMERGE_VALUES %0(<16 x s8>) + %0:fpr(<16 x i8>) = COPY $q0 + %2:fpr(i8), %3:fpr(i8), %4:fpr(i8), %5:fpr(i8), %6:fpr(i8), %7:fpr(i8), %8:fpr(i8), %9:fpr(i8), %10:fpr(i8), %11:fpr(i8), %12:fpr(i8), %13:fpr(i8), %14:fpr(i8), %15:fpr(i8), %16:fpr(i8), %17:fpr(i8) = G_UNMERGE_VALUES %0(<16 x i8>) - %1:fpr(<16 x s8>) = G_BUILD_VECTOR %2:fpr(s8), %3:fpr(s8), %4:fpr(s8), %5:fpr(s8), %6:fpr(s8), %7:fpr(s8), %8:fpr(s8), %9:fpr(s8), %10:fpr(s8), %11:fpr(s8), %12:fpr(s8), %13:fpr(s8), %14:fpr(s8), %15:fpr(s8), %16:fpr(s8), %17:fpr(s8) - $q0 = COPY %1(<16 x s8>) + %1:fpr(<16 x i8>) = G_BUILD_VECTOR %2:fpr(i8), %3:fpr(i8), %4:fpr(i8), %5:fpr(i8), %6:fpr(i8), %7:fpr(i8), %8:fpr(i8), %9:fpr(i8), %10:fpr(i8), %11:fpr(i8), %12:fpr(i8), %13:fpr(i8), %14:fpr(i8), %15:fpr(i8), %16:fpr(i8), %17:fpr(i8) + $q0 = COPY %1(<16 x i8>) RET_ReallyLR implicit $q0 ... --- @@ -404,10 +404,10 @@ body: | ; CHECK-NEXT: $d0 = COPY [[COPY1]] ; CHECK-NEXT: $d1 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<2 x s32>), %2:fpr(<2 x s32>) = G_UNMERGE_VALUES %0(<4 x s32>) - $d0 = COPY %1(<2 x s32>) - $d1 = COPY %2(<2 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<2 x i32>), %2:fpr(<2 x i32>) = G_UNMERGE_VALUES %0(<4 x i32>) + $d0 = COPY %1(<2 x i32>) + $d1 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... --- @@ -430,10 +430,10 @@ body: | ; CHECK-NEXT: $s0 = COPY [[COPY1]] ; CHECK-NEXT: $s1 = COPY [[DUPi32_]] ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<2 x s16>), %2:fpr(<2 x s16>) = G_UNMERGE_VALUES %0(<4 x s16>) - $s0 = COPY %1(<2 x s16>) - $s1 = COPY %2(<2 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<2 x i16>), %2:fpr(<2 x i16>) = G_UNMERGE_VALUES %0(<4 x i16>) + $s0 = COPY %1(<2 x i16>) + $s1 = COPY %2(<2 x i16>) RET_ReallyLR implicit $s0 ... --- @@ -454,10 +454,10 @@ body: | ; CHECK-NEXT: $d0 = COPY [[COPY1]] ; CHECK-NEXT: $d1 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 - %0:fpr(s128) = COPY $q0 - %1:fpr(s64), %2:fpr(s64) = G_UNMERGE_VALUES %0(s128) - $d0 = COPY %1(s64) - $d1 = COPY %2(s64) + %0:fpr(i128) = COPY $q0 + %1:fpr(i64), %2:fpr(i64) = G_UNMERGE_VALUES %0(i128) + $d0 = COPY %1(i64) + $d1 = COPY %2(i64) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -480,10 +480,10 @@ body: | ; CHECK-NEXT: $h0 = COPY [[COPY1]] ; CHECK-NEXT: $h1 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0, implicit $h1 - %0:fpr(s32) = COPY $s0 - %1:fpr(s16), %2:fpr(s16) = G_UNMERGE_VALUES %0(s32) - $h0 = COPY %1(s16) - $h1 = COPY %2(s16) + %0:fpr(i32) = COPY $s0 + %1:fpr(i16), %2:fpr(i16) = G_UNMERGE_VALUES %0(i32) + $h0 = COPY %1(i16) + $h1 = COPY %2(i16) RET_ReallyLR implicit $h0, implicit $h1 ... --- @@ -506,10 +506,10 @@ body: | ; CHECK-NEXT: $s0 = COPY [[COPY1]] ; CHECK-NEXT: $s1 = COPY [[DUPi32_]] ; CHECK-NEXT: RET_ReallyLR implicit $s0, implicit $s1 - %0:fpr(s64) = COPY $d0 - %1:fpr(s32), %2:fpr(s32) = G_UNMERGE_VALUES %0(s64) - $s0 = COPY %1(s32) - $s1 = COPY %2(s32) + %0:fpr(i64) = COPY $d0 + %1:fpr(i32), %2:fpr(i32) = G_UNMERGE_VALUES %0(i64) + $s0 = COPY %1(i32) + $s1 = COPY %2(i32) RET_ReallyLR implicit $s0, implicit $s1 ... --- @@ -540,12 +540,12 @@ body: | ; CHECK-NEXT: $h2 = COPY [[DUPi16_1]] ; CHECK-NEXT: $h3 = COPY [[DUPi16_2]] ; CHECK-NEXT: RET_ReallyLR implicit $h0, implicit $h1, implicit $h2, implicit $h3 - %0:fpr(s64) = COPY $d0 - %1:fpr(s16), %2:fpr(s16), %3:fpr(s16), %4:fpr(s16) = G_UNMERGE_VALUES %0(s64) - $h0 = COPY %1(s16) - $h1 = COPY %2(s16) - $h2 = COPY %3(s16) - $h3 = COPY %4(s16) + %0:fpr(i64) = COPY $d0 + %1:fpr(i16), %2:fpr(i16), %3:fpr(i16), %4:fpr(i16) = G_UNMERGE_VALUES %0(i64) + $h0 = COPY %1(i16) + $h1 = COPY %2(i16) + $h2 = COPY %3(i16) + $h3 = COPY %4(i16) RET_ReallyLR implicit $h0, implicit $h1, implicit $h2, implicit $h3 ... --- @@ -576,11 +576,11 @@ body: | ; CHECK-NEXT: $b2 = COPY [[DUPi8_1]] ; CHECK-NEXT: $b3 = COPY [[DUPi8_2]] ; CHECK-NEXT: RET_ReallyLR implicit $b0, implicit $b1, implicit $b2, implicit $b3 - %0:fpr(s32) = COPY $s0 - %1:fpr(s8), %2:fpr(s8), %3:fpr(s8), %4:fpr(s8) = G_UNMERGE_VALUES %0(s32) - $b0 = COPY %1(s8) - $b1 = COPY %2(s8) - $b2 = COPY %3(s8) - $b3 = COPY %4(s8) + %0:fpr(i32) = COPY $s0 + %1:fpr(i8), %2:fpr(i8), %3:fpr(i8), %4:fpr(i8) = G_UNMERGE_VALUES %0(i32) + $b0 = COPY %1(i8) + $b1 = COPY %2(i8) + $b2 = COPY %3(i8) + $b3 = COPY %4(i8) RET_ReallyLR implicit $b0, implicit $b1, implicit $b2, implicit $b3 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-usube.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-usube.mir index fa8799653a570..aa4f602ac09d7 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-usube.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-usube.mir @@ -23,12 +23,12 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SBCSXr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s64), %4:gpr(s32) = G_USUBE %0, %1, %2 - $x0 = COPY %3(s64) - $w1 = COPY %4(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i64), %4:gpr(i32) = G_USUBE %0, %1, %2 + $x0 = COPY %3(i64) + $w1 = COPY %4(i32) RET_ReallyLR implicit $x0, implicit $w1 ... ... @@ -54,12 +54,12 @@ body: | ; CHECK-NEXT: $w0 = COPY [[SBCSWr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32), %4:gpr(s32) = G_USUBE %0, %1, %2 - $w0 = COPY %3(s32) - $w1 = COPY %4(s32) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32), %4:gpr(i32) = G_USUBE %0, %1, %2 + $w0 = COPY %3(i32) + $w1 = COPY %4(i32) RET_ReallyLR implicit $w0, implicit $w1 ... ... @@ -85,14 +85,14 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] ; CHECK-NEXT: $x1 = COPY [[SBCSXr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %8:gpr(s64), %12:gpr(s32) = G_USUBO %0, %2 - %9:gpr(s64), %13:gpr(s32) = G_USUBE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %8:gpr(i64), %12:gpr(i32) = G_USUBO %0, %2 + %9:gpr(i64), %13:gpr(i32) = G_USUBE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -120,15 +120,15 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SBCSXr]] ; CHECK-NEXT: $x1 = COPY [[SBCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %6:gpr(s32) = G_CONSTANT i32 1 - %8:gpr(s64), %12:gpr(s32) = G_USUBE %0, %2, %6 - %9:gpr(s64), %13:gpr(s32) = G_USUBE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %6:gpr(i32) = G_CONSTANT i32 1 + %8:gpr(i64), %12:gpr(i32) = G_USUBE %0, %2, %6 + %9:gpr(i64), %13:gpr(i32) = G_USUBE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -160,19 +160,19 @@ body: | ; CHECK-NEXT: $x1 = COPY [[SBCSXr]] ; CHECK-NEXT: $x2 = COPY [[SBCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %4:gpr(s64) = COPY $x4 - %5:gpr(s64) = COPY $x5 - %6:gpr(s64) = COPY $x6 - %7:gpr(s64), %11:gpr(s32) = G_USUBO %0, %4 - %8:gpr(s64), %12:gpr(s32) = G_USUBE %1, %5, %11 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %4:gpr(i64) = COPY $x4 + %5:gpr(i64) = COPY $x5 + %6:gpr(i64) = COPY $x6 + %7:gpr(i64), %11:gpr(i32) = G_USUBO %0, %4 + %8:gpr(i64), %12:gpr(i32) = G_USUBE %1, %5, %11 ; carry-in is not produced by previous instruction - %9:gpr(s64), %13:gpr(s32) = G_USUBE %2, %6, %11 - $x0 = COPY %7(s64) - $x1 = COPY %8(s64) - $x2 = COPY %9(s64) + %9:gpr(i64), %13:gpr(i32) = G_USUBE %2, %6, %11 + $x0 = COPY %7(i64) + $x1 = COPY %8(i64) + $x2 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 ... ... @@ -197,12 +197,12 @@ body: | ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %4:gpr(s64), %5:gpr(s32) = G_USUBO %0, %2 - %6:gpr(s64), %7:gpr(s32) = G_USUBE %1, %3, %5 - $w0 = COPY %7(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %4:gpr(i64), %5:gpr(i32) = G_USUBO %0, %2 + %6:gpr(i64), %7:gpr(i32) = G_USUBE %1, %3, %5 + $w0 = COPY %7(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-usubo.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-usubo.mir index a9295194779c8..dd3b9453ac6b8 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-usubo.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-usubo.mir @@ -22,9 +22,9 @@ body: | ; CHECK-NEXT: $w0 = COPY [[SUBSWrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %3:gpr(s32), %4:gpr(s32) = G_USUBO %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %3:gpr(i32), %4:gpr(i32) = G_USUBO %0, %1 $w0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $w0, implicit $w1 @@ -50,9 +50,9 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %3:gpr(s64), %4:gpr(s32) = G_USUBO %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %3:gpr(i64), %4:gpr(i32) = G_USUBO %0, %1 $x0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $x0, implicit $w1 @@ -75,9 +75,9 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 16 - %add:gpr(s32), %overflow:gpr(s32) = G_USUBO %copy, %constant + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 16 + %add:gpr(i32), %overflow:gpr(i32) = G_USUBO %copy, %constant $w0 = COPY %add RET_ReallyLR implicit $w0 @@ -100,12 +100,12 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWrs %copy1, %copy2, 16, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy1:gpr(s32) = COPY $w0 - %copy2:gpr(s32) = COPY $w1 - %constant:gpr(s32) = G_CONSTANT i32 16 - %shift:gpr(s32) = G_SHL %copy2(s32), %constant(s32) - %add:gpr(s32), %overflow:gpr(s32) = G_USUBO %copy1, %shift - $w0 = COPY %add(s32) + %copy1:gpr(i32) = COPY $w0 + %copy2:gpr(i32) = COPY $w1 + %constant:gpr(i32) = G_CONSTANT i32 16 + %shift:gpr(i32) = G_SHL %copy2(i32), %constant(i32) + %add:gpr(i32), %overflow:gpr(i32) = G_USUBO %copy1, %shift + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -126,10 +126,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 -16 - %add:gpr(s32), %overflow:gpr(s32) = G_USUBO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 -16 + %add:gpr(i32), %overflow:gpr(i32) = G_USUBO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -151,11 +151,11 @@ body: | ; CHECK-NEXT: %add:gpr64 = SUBSXrx %reg0, %reg1, 18, implicit-def $nzcv ; CHECK-NEXT: $x0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:gpr(s64) = COPY $x0 - %reg1:gpr(s32) = COPY $w0 - %ext:gpr(s64) = G_ZEXT %reg1(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %add:gpr(s64), %flags:gpr(s32) = G_USUBO %reg0, %shift - $x0 = COPY %add(s64) + %reg0:gpr(i64) = COPY $x0 + %reg1:gpr(i32) = COPY $w0 + %ext:gpr(i64) = G_ZEXT %reg1(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %add:gpr(i64), %flags:gpr(i32) = G_USUBO %reg0, %shift + $x0 = COPY %add(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-uzp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-uzp.mir index 83ca512889cc1..e5925852058e3 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-uzp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-uzp.mir @@ -22,10 +22,10 @@ body: | ; CHECK-NEXT: [[UZP1v4i32_:%[0-9]+]]:fpr128 = UZP1v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[UZP1v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_UZP1 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_UZP1 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -46,10 +46,10 @@ body: | ; CHECK-NEXT: [[UZP2v4i32_:%[0-9]+]]:fpr128 = UZP2v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[UZP2v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_UZP2 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_UZP2 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-icmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-icmp.mir index 4ee74f3a952a1..8c5cd27e41ca3 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-icmp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-icmp.mir @@ -510,12 +510,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(eq), %7(<2 x i32>), %8 @@ -800,12 +800,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(ugt), %7(<2 x i32>), %8 @@ -1090,12 +1090,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(uge), %7(<2 x i32>), %8 @@ -1380,12 +1380,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(ult), %7(<2 x i32>), %8 @@ -1670,12 +1670,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(ule), %7(<2 x i32>), %8 @@ -1966,13 +1966,13 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %14:gpr(s32) = G_CONSTANT i32 16 - %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(s32), %14(s32) + %14:gpr(i32) = G_CONSTANT i32 16 + %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(i32), %14(i32) %16:fpr(<2 x i32>) = COPY %2(<2 x i32>) %17:fpr(<2 x i32>) = G_SHL %16, %15(<2 x i32>) %7:fpr(<2 x i32>) = G_ASHR %17, %15(<2 x i32>) - %10:gpr(s32) = G_CONSTANT i32 16 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 16 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %13:fpr(<2 x i32>) = G_SHL %12, %11(<2 x i32>) %8:fpr(<2 x i32>) = G_ASHR %13, %11(<2 x i32>) @@ -2264,13 +2264,13 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %14:gpr(s32) = G_CONSTANT i32 16 - %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(s32), %14(s32) + %14:gpr(i32) = G_CONSTANT i32 16 + %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(i32), %14(i32) %16:fpr(<2 x i32>) = COPY %2(<2 x i32>) %17:fpr(<2 x i32>) = G_SHL %16, %15(<2 x i32>) %7:fpr(<2 x i32>) = G_ASHR %17, %15(<2 x i32>) - %10:gpr(s32) = G_CONSTANT i32 16 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 16 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %13:fpr(<2 x i32>) = G_SHL %12, %11(<2 x i32>) %8:fpr(<2 x i32>) = G_ASHR %13, %11(<2 x i32>) @@ -2562,13 +2562,13 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %14:gpr(s32) = G_CONSTANT i32 16 - %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(s32), %14(s32) + %14:gpr(i32) = G_CONSTANT i32 16 + %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(i32), %14(i32) %16:fpr(<2 x i32>) = COPY %2(<2 x i32>) %17:fpr(<2 x i32>) = G_SHL %16, %15(<2 x i32>) %7:fpr(<2 x i32>) = G_ASHR %17, %15(<2 x i32>) - %10:gpr(s32) = G_CONSTANT i32 16 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 16 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %13:fpr(<2 x i32>) = G_SHL %12, %11(<2 x i32>) %8:fpr(<2 x i32>) = G_ASHR %13, %11(<2 x i32>) @@ -2860,13 +2860,13 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %14:gpr(s32) = G_CONSTANT i32 16 - %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(s32), %14(s32) + %14:gpr(i32) = G_CONSTANT i32 16 + %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(i32), %14(i32) %16:fpr(<2 x i32>) = COPY %2(<2 x i32>) %17:fpr(<2 x i32>) = G_SHL %16, %15(<2 x i32>) %7:fpr(<2 x i32>) = G_ASHR %17, %15(<2 x i32>) - %10:gpr(s32) = G_CONSTANT i32 16 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 16 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %13:fpr(<2 x i32>) = G_SHL %12, %11(<2 x i32>) %8:fpr(<2 x i32>) = G_ASHR %13, %11(<2 x i32>) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-shift.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-shift.mir index 605ab99094719..9371e2eac5e4a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-shift.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-shift.mir @@ -58,8 +58,8 @@ body: | ; CHECK-NEXT: $d0 = COPY [[SHLv2i32_shift]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:fpr(<2 x i32>) = COPY $d0 - %2:gpr(s32) = G_CONSTANT i32 24 - %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(s32), %2(s32) + %2:gpr(i32) = G_CONSTANT i32 24 + %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(i32), %2(i32) %3:fpr(<2 x i32>) = G_SHL %0, %1(<2 x i32>) $d0 = COPY %3(<2 x i32>) RET_ReallyLR implicit $d0 @@ -94,8 +94,8 @@ body: | ; CHECK-NEXT: $d0 = COPY [[USHLv2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:fpr(<2 x i32>) = COPY $d0 - %2:gpr(s32) = G_CONSTANT i32 40 - %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(s32), %2(s32) + %2:gpr(i32) = G_CONSTANT i32 40 + %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(i32), %2(i32) %3:fpr(<2 x i32>) = G_SHL %0, %1(<2 x i32>) $d0 = COPY %3(<2 x i32>) RET_ReallyLR implicit $d0 @@ -159,8 +159,8 @@ body: | ; CHECK-NEXT: $q0 = COPY [[SHLv4i32_shift]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:fpr(<4 x i32>) = COPY $q0 - %2:gpr(s32) = G_CONSTANT i32 24 - %1:fpr(<4 x i32>) = G_BUILD_VECTOR %2(s32), %2(s32), %2(s32), %2(s32) + %2:gpr(i32) = G_CONSTANT i32 24 + %1:fpr(<4 x i32>) = G_BUILD_VECTOR %2(i32), %2(i32), %2(i32), %2(i32) %3:fpr(<4 x i32>) = G_SHL %0, %1(<4 x i32>) $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 @@ -224,8 +224,8 @@ body: | ; CHECK-NEXT: $q0 = COPY [[SHLv2i64_shift]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:fpr(<2 x i64>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 24 - %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(s64), %2(s64) + %2:gpr(i64) = G_CONSTANT i64 24 + %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(i64), %2(i64) %3:fpr(<2 x i64>) = G_SHL %0, %1(<2 x i64>) $q0 = COPY %3(<2 x i64>) RET_ReallyLR implicit $q0 @@ -261,8 +261,8 @@ body: | ; CHECK-NEXT: $q0 = COPY [[USHLv2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:fpr(<2 x i64>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 70 - %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(s64), %2(s64) + %2:gpr(i64) = G_CONSTANT i64 70 + %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(i64), %2(i64) %3:fpr(<2 x i64>) = G_SHL %0, %1(<2 x i64>) $q0 = COPY %3(<2 x i64>) RET_ReallyLR implicit $q0 @@ -619,8 +619,8 @@ body: | ; CHECK-NEXT: $d0 = COPY [[SHLv2i32_shift]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:fpr(<2 x i32>) = COPY $d0 - %2:gpr(s32) = G_CONSTANT i32 24 - %1:fpr(<2 x i32>) = G_DUP %2(s32) + %2:gpr(i32) = G_CONSTANT i32 24 + %1:fpr(<2 x i32>) = G_DUP %2(i32) %3:fpr(<2 x i32>) = G_SHL %0, %1(<2 x i32>) $d0 = COPY %3(<2 x i32>) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-with-no-legality-check.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-with-no-legality-check.mir index d22305e441936..68b396029536a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-with-no-legality-check.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-with-no-legality-check.mir @@ -260,11 +260,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: $noreg = PATCHABLE_RET [[LDRBBui]] %2:gpr(p0) = COPY $x0 - %0:gpr(s32) = G_LOAD %2(p0) :: (load (s8)) - $noreg = PATCHABLE_RET %0(s32) + %0:gpr(i32) = G_LOAD %2(p0) :: (load (i8)) + $noreg = PATCHABLE_RET %0(i32) ... # The rules that generated this test has changed. The generator should be rerun @@ -288,14 +288,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[LDRBui]] ; CHECK-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[COPY1]], 0, 7 ; CHECK-NEXT: $noreg = PATCHABLE_RET [[UBFMWri]] %2:gpr(p0) = COPY $x0 - %0:fpr(s8) = G_LOAD %2(p0) :: (load (s8)) - %1:gpr(s32) = G_ZEXT %0(s8) - $noreg = PATCHABLE_RET %1(s32) + %0:fpr(i8) = G_LOAD %2(p0) :: (load (i8)) + %1:gpr(i32) = G_ZEXT %0(i8) + $noreg = PATCHABLE_RET %1(i32) ... --- diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-zext-as-copy.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-zext-as-copy.mir index e6b400f324133..e0964ac628db4 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-zext-as-copy.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-zext-as-copy.mir @@ -23,13 +23,13 @@ body: | ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64common = IMPLICIT_DEF - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[DEF]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[DEF]], 0 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDRBBui]], %subreg.sub_32 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: [[ANDXri:%[0-9]+]]:gpr64sp = ANDXri [[COPY]], 4096 ; CHECK-NEXT: $x0 = COPY [[ANDXri]] %3:gpr(p0) = G_IMPLICIT_DEF - %2:gpr(i8) = G_LOAD %3(p0) :: (load (s8)) + %2:gpr(i8) = G_LOAD %3(p0) :: (load (i8)) %4:gpr(i64) = G_ZEXT %2(i8) %5:gpr(i64) = G_CONSTANT i64 1 %6:gpr(i64) = G_AND %4, %5 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-zextload.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-zextload.mir index b6b386acdbd9a..3ca1335fe7524 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-zextload.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-zextload.mir @@ -13,10 +13,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] %0:gpr(p0) = COPY $x0 - %1:gpr(i32) = G_ZEXTLOAD %0 :: (load (s16)) + %1:gpr(i32) = G_ZEXTLOAD %0 :: (load (i16)) $w0 = COPY %1(i32) ... --- @@ -31,11 +31,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0:gpr(p0) = COPY $x0 - %1:gpr(s16) = G_LOAD %0 :: (load (s16)) + %1:gpr(i16) = G_LOAD %0 :: (load (i16)) %2:gpr(i32) = G_ZEXT %1 $w0 = COPY %2(i32) ... @@ -51,12 +51,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32)) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDRWui]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (s32)) + %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (i32)) $x0 = COPY %2(i64) RET_ReallyLR implicit $x0 @@ -73,12 +73,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDRHHui]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (s16)) + %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (i16)) $x0 = COPY %2(i64) RET_ReallyLR implicit $x0 @@ -95,12 +95,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDRBBui]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (s8)) + %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (i8)) $x0 = COPY %2(i64) RET_ReallyLR implicit $x0 @@ -117,11 +117,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: $w0 = COPY [[LDRBBui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load (i8)) $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 @@ -138,11 +138,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load (i16)) $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 @@ -160,11 +160,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load unordered (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load unordered (i8)) ; CHECK-NEXT: $w0 = COPY [[LDRBBui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load unordered (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load unordered (i8)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -182,11 +182,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load monotonic (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load monotonic (i8)) ; CHECK-NEXT: $w0 = COPY [[LDRBBui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load monotonic (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load monotonic (i8)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -204,11 +204,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load acquire (s8)) + ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load acquire (i8)) ; CHECK-NEXT: $w0 = COPY [[LDARB]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load acquire (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load acquire (i8)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -226,11 +226,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load seq_cst (s8)) + ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load seq_cst (i8)) ; CHECK-NEXT: $w0 = COPY [[LDARB]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load seq_cst (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load seq_cst (i8)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -248,11 +248,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load unordered (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load unordered (i16)) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load unordered (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load unordered (i16)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -270,11 +270,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load monotonic (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load monotonic (i16)) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load monotonic (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load monotonic (i16)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -292,11 +292,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARH:%[0-9]+]]:gpr32 = LDARH [[COPY]] :: (load acquire (s16)) + ; CHECK-NEXT: [[LDARH:%[0-9]+]]:gpr32 = LDARH [[COPY]] :: (load acquire (i16)) ; CHECK-NEXT: $w0 = COPY [[LDARH]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load acquire (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load acquire (i16)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -314,11 +314,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARH:%[0-9]+]]:gpr32 = LDARH [[COPY]] :: (load seq_cst (s16)) + ; CHECK-NEXT: [[LDARH:%[0-9]+]]:gpr32 = LDARH [[COPY]] :: (load seq_cst (i16)) ; CHECK-NEXT: $w0 = COPY [[LDARH]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load seq_cst (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load seq_cst (i16)) $w0 = COPY %2 RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-zip.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-zip.mir index da25425708244..6f7f617782878 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-zip.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-zip.mir @@ -23,10 +23,10 @@ body: | ; CHECK-NEXT: [[ZIP1v2i32_:%[0-9]+]]:fpr64 = ZIP1v2i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[ZIP1v2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_ZIP1 %0, %1 - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_ZIP1 %0, %1 + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... --- @@ -47,10 +47,10 @@ body: | ; CHECK-NEXT: [[ZIP1v2i64_:%[0-9]+]]:fpr128 = ZIP1v2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ZIP1v2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_ZIP1 %0, %1 - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_ZIP1 %0, %1 + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -70,10 +70,10 @@ body: | ; CHECK-NEXT: [[ZIP1v4i32_:%[0-9]+]]:fpr128 = ZIP1v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ZIP1v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_ZIP1 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_ZIP1 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -94,10 +94,10 @@ body: | ; CHECK-NEXT: [[ZIP2v2i32_:%[0-9]+]]:fpr64 = ZIP2v2i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[ZIP2v2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_ZIP2 %0, %1 - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_ZIP2 %0, %1 + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... --- @@ -118,10 +118,10 @@ body: | ; CHECK-NEXT: [[ZIP2v2i64_:%[0-9]+]]:fpr128 = ZIP2v2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ZIP2v2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_ZIP2 %0, %1 - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_ZIP2 %0, %1 + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -141,8 +141,8 @@ body: | ; CHECK-NEXT: [[ZIP2v4i32_:%[0-9]+]]:fpr128 = ZIP2v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ZIP2v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_ZIP2 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_ZIP2 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll b/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll index 6c6a9714f7deb..f1808fb4e87c0 100644 --- a/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll +++ b/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll @@ -20,6 +20,12 @@ ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i16 ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i32 ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i64 +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fadd_fast +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmul_fast +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmin +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmax +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fminimum +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmaximum ; ; CHECK-BF16-GI: warning: Instruction selection used fallback path for test_fptosi_i8 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_fptosi_i16 @@ -37,6 +43,13 @@ ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i16 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i32 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i64 +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fadd_fast +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmul_fast +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmin +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmax +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fminimum +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmaximum +; ; define <4 x bfloat> @test_build(<4 x bfloat> %a) { @@ -6504,4 +6517,584 @@ define <4 x bfloat> @test_fmuladd(<4 x bfloat> %a, <4 x bfloat> %b, <4 x bfloat> ret <4 x bfloat> %r } +define bfloat @test_reduce_fadd(bfloat %a, <4 x bfloat> %b) #0 { +; CHECK-CVT-SD-LABEL: test_reduce_fadd: +; CHECK-CVT-SD: // %bb.0: +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-SD-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-CVT-SD-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s0, s2 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[1] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[2] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[3] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s1, w9 +; CHECK-CVT-SD-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s1, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w8, w9, w8 +; CHECK-CVT-SD-NEXT: add w8, w10, w8 +; CHECK-CVT-SD-NEXT: lsr w8, w8, #16 +; CHECK-CVT-SD-NEXT: fmov s0, w8 +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-SD-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fadd: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-BF16-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-BF16-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[1] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[2] +; CHECK-BF16-NEXT: mov h1, v1.h[3] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret +; +; CHECK-CVT-GI-LABEL: test_reduce_fadd: +; CHECK-CVT-GI: // %bb.0: +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-GI-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-CVT-GI-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s0, s2 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[1] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[2] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[3] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s1, w9 +; CHECK-CVT-GI-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s1, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w8, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: add w8, w8, w10 +; CHECK-CVT-GI-NEXT: csel w8, w9, w8, vs +; CHECK-CVT-GI-NEXT: lsr w8, w8, #16 +; CHECK-CVT-GI-NEXT: fmov s0, w8 +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-GI-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fadd(bfloat %a, <4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fadd_fast(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fadd_fast: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fadd s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fadd s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fadd s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fadd_fast: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: mov h3, v0.h[2] +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v3.4s, v3.4h, #16 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s1 +; CHECK-BF16-NEXT: fadd s1, s3, s2 +; CHECK-BF16-NEXT: fadd s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call fast bfloat @llvm.vector.reduce.fadd(bfloat -0.0, <4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmul(bfloat %a, <4 x bfloat> %b) #0 { +; CHECK-CVT-SD-LABEL: test_reduce_fmul: +; CHECK-CVT-SD: // %bb.0: +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-SD-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-CVT-SD-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s0, s2 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[1] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[2] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[3] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s1, w9 +; CHECK-CVT-SD-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s1, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w8, w9, w8 +; CHECK-CVT-SD-NEXT: add w8, w10, w8 +; CHECK-CVT-SD-NEXT: lsr w8, w8, #16 +; CHECK-CVT-SD-NEXT: fmov s0, w8 +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-SD-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmul: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-BF16-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-BF16-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[1] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[2] +; CHECK-BF16-NEXT: mov h1, v1.h[3] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret +; +; CHECK-CVT-GI-LABEL: test_reduce_fmul: +; CHECK-CVT-GI: // %bb.0: +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-GI-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-CVT-GI-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s0, s2 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[1] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[2] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[3] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s1, w9 +; CHECK-CVT-GI-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s1, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w8, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: add w8, w8, w10 +; CHECK-CVT-GI-NEXT: csel w8, w9, w8, vs +; CHECK-CVT-GI-NEXT: lsr w8, w8, #16 +; CHECK-CVT-GI-NEXT: fmov s0, w8 +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-GI-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmul(bfloat %a, <4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmul_fast(<4 x bfloat> %b) #0 { +; CHECK-LABEL: test_reduce_fmul_fast: +; CHECK: // %bb.0: +; CHECK-NEXT: movi d0, #0000000000000000 +; CHECK-NEXT: ret + %r = call fast bfloat @llvm.vector.reduce.fmul(bfloat -0.0, <4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmin(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmin: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fminnm s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmin: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: mov h0, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmin(<4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmax(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmax: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmax: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: mov h0, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmax(<4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fminimum(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fminimum: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmin s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fminimum: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: mov h0, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fminimum(<4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmaximum(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmaximum: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmax s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmaximum: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: mov h0, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmaximum(<4 x bfloat> %b) + ret bfloat %r +} + attributes #0 = { nounwind } diff --git a/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll b/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll index 971d9e2a6e2b5..2453b36f0873d 100644 --- a/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll +++ b/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll @@ -25,6 +25,12 @@ ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i16 ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i32 ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i64 +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fadd_fast +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmul_fast +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmin +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmax +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fminimum +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmaximum ; ; CHECK-BF16-GI: warning: Instruction selection used fallback path for test_fptosi_i8 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_fptosi_v16i8 @@ -46,6 +52,13 @@ ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i16 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i32 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i64 +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fadd_fast +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmul_fast +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmin +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmax +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fminimum +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmaximum +; ; define <8 x bfloat> @test_build(<8 x bfloat> %a) { @@ -13769,4 +13782,1008 @@ define <8 x bfloat> @test_fmuladd(<8 x bfloat> %a, <8 x bfloat> %b, <8 x bfloat> ret <8 x bfloat> %r } +define bfloat @test_reduce_fadd(bfloat %a, <8 x bfloat> %b) #0 { +; CHECK-CVT-SD-LABEL: test_reduce_fadd: +; CHECK-CVT-SD: // %bb.0: +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-SD-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s0, s2 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[1] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[2] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[3] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[4] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[5] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[6] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[7] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s1, w9 +; CHECK-CVT-SD-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s1, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w8, w9, w8 +; CHECK-CVT-SD-NEXT: add w8, w10, w8 +; CHECK-CVT-SD-NEXT: lsr w8, w8, #16 +; CHECK-CVT-SD-NEXT: fmov s0, w8 +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-SD-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fadd: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-BF16-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[1] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[2] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[3] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[4] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[5] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[6] +; CHECK-BF16-NEXT: mov h1, v1.h[7] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret +; +; CHECK-CVT-GI-LABEL: test_reduce_fadd: +; CHECK-CVT-GI: // %bb.0: +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-GI-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s0, s2 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[1] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[2] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[3] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[4] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[5] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[6] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[7] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s1, w9 +; CHECK-CVT-GI-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s1, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w8, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: add w8, w8, w10 +; CHECK-CVT-GI-NEXT: csel w8, w9, w8, vs +; CHECK-CVT-GI-NEXT: lsr w8, w8, #16 +; CHECK-CVT-GI-NEXT: fmov s0, w8 +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-GI-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fadd(bfloat %a, <8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fadd_fast(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fadd_fast: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: shll2 v1.4s, v0.8h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: fadd v0.4s, v0.4s, v1.4s +; CHECK-CVT-NEXT: faddp v0.4s, v0.4s, v0.4s +; CHECK-CVT-NEXT: faddp s0, v0.2s +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fadd_fast: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: shll2 v1.4s, v0.8h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd v0.4s, v0.4s, v1.4s +; CHECK-BF16-NEXT: faddp v0.4s, v0.4s, v0.4s +; CHECK-BF16-NEXT: faddp s0, v0.2s +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call fast bfloat @llvm.vector.reduce.fadd(bfloat -0.0, <8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmul(bfloat %a, <8 x bfloat> %b) #0 { +; CHECK-CVT-SD-LABEL: test_reduce_fmul: +; CHECK-CVT-SD: // %bb.0: +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-SD-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s0, s2 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[1] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[2] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[3] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[4] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[5] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[6] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[7] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s1, w9 +; CHECK-CVT-SD-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s1, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w8, w9, w8 +; CHECK-CVT-SD-NEXT: add w8, w10, w8 +; CHECK-CVT-SD-NEXT: lsr w8, w8, #16 +; CHECK-CVT-SD-NEXT: fmov s0, w8 +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-SD-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmul: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-BF16-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[1] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[2] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[3] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[4] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[5] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[6] +; CHECK-BF16-NEXT: mov h1, v1.h[7] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret +; +; CHECK-CVT-GI-LABEL: test_reduce_fmul: +; CHECK-CVT-GI: // %bb.0: +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-GI-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s0, s2 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[1] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[2] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[3] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[4] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[5] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[6] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[7] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s1, w9 +; CHECK-CVT-GI-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s1, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w8, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: add w8, w8, w10 +; CHECK-CVT-GI-NEXT: csel w8, w9, w8, vs +; CHECK-CVT-GI-NEXT: lsr w8, w8, #16 +; CHECK-CVT-GI-NEXT: fmov s0, w8 +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-GI-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmul(bfloat %a, <8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmul_fast(<8 x bfloat> %b) #0 { +; CHECK-LABEL: test_reduce_fmul_fast: +; CHECK: // %bb.0: +; CHECK-NEXT: movi d0, #0000000000000000 +; CHECK-NEXT: ret + %r = call fast bfloat @llvm.vector.reduce.fmul(bfloat -0.0, <8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmin(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmin: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[4] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[5] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[6] +; CHECK-CVT-NEXT: mov h0, v0.h[7] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fminnm s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmin: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[4] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[5] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[6] +; CHECK-BF16-NEXT: mov h0, v0.h[7] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmin(<8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmax(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmax: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[4] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[5] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[6] +; CHECK-CVT-NEXT: mov h0, v0.h[7] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmax: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[4] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[5] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[6] +; CHECK-BF16-NEXT: mov h0, v0.h[7] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmax(<8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fminimum(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fminimum: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[4] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[5] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[6] +; CHECK-CVT-NEXT: mov h0, v0.h[7] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmin s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fminimum: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[4] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[5] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[6] +; CHECK-BF16-NEXT: mov h0, v0.h[7] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fminimum(<8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmaximum(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmaximum: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[4] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[5] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[6] +; CHECK-CVT-NEXT: mov h0, v0.h[7] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmax s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmaximum: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[4] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[5] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[6] +; CHECK-BF16-NEXT: mov h0, v0.h[7] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmaximum(<8 x bfloat> %b) + ret bfloat %r +} + attributes #0 = { nounwind } diff --git a/llvm/test/CodeGen/AArch64/branch-folder-hoist-disable.mir b/llvm/test/CodeGen/AArch64/branch-folder-hoist-disable.mir new file mode 100644 index 0000000000000..4ae1d9ac04320 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/branch-folder-hoist-disable.mir @@ -0,0 +1,46 @@ +# RUN: llc -o - %s -mtriple=aarch64 -run-pass branch-folder -verify-machineinstrs | FileCheck %s --check-prefix=HOIST +# RUN: llc -o - %s -mtriple=aarch64 -run-pass branch-folder -branch-folder-hoist-common-code=false -verify-machineinstrs | FileCheck %s --check-prefix=NOHOIST + +# Check that -branch-folder-hoist-common-code=false disables the common-code +# hoisting sub-phase of BranchFolding. With hoisting enabled (default) the +# common "ADDXri $x0, 1, 0" is hoisted from both successors into bb.0; with +# hoisting disabled it must remain duplicated in bb.1 and bb.2. + +name: func +tracksRegLiveness: true +body: | + bb.0: + ; HOIST-LABEL: name: func + ; HOIST-LABEL: bb.0: + ; HOIST: $x0 = ADDXri $x0, 1, 0 + ; HOIST: CBZX $x1, %bb.2 + ; + ; NOHOIST-LABEL: name: func + ; NOHOIST-LABEL: bb.0: + ; NOHOIST-NOT: $x0 = ADDXri $x0, 1, 0 + ; NOHOIST: CBZX $x1, %bb.2 + liveins: $x0, $x1 + CBZX $x1, %bb.2 + + bb.1: + ; HOIST-LABEL: bb.1: + ; HOIST-NOT: $x0 = ADDXri $x0, 1, 0 + ; + ; NOHOIST-LABEL: bb.1: + ; NOHOIST: $x0 = ADDXri $x0, 1, 0 + liveins: $x0 + $x0 = ADDXri $x0, 1, 0 + $x0 = ADDXri $x0, 2, 0 + RET_ReallyLR implicit $x0 + + bb.2: + ; HOIST-LABEL: bb.2: + ; HOIST-NOT: $x0 = ADDXri $x0, 1, 0 + ; + ; NOHOIST-LABEL: bb.2: + ; NOHOIST: $x0 = ADDXri $x0, 1, 0 + liveins: $x0 + $x0 = ADDXri $x0, 1, 0 + $x0 = ADDXri $x0, 3, 0 + RET_ReallyLR implicit $x0 +... diff --git a/llvm/test/CodeGen/AArch64/branch-folder-reorder-disable.mir b/llvm/test/CodeGen/AArch64/branch-folder-reorder-disable.mir new file mode 100644 index 0000000000000..d868d642e04aa --- /dev/null +++ b/llvm/test/CodeGen/AArch64/branch-folder-reorder-disable.mir @@ -0,0 +1,55 @@ +# RUN: llc -o - %s -mtriple=aarch64 -run-pass branch-folder -verify-machineinstrs | FileCheck %s --check-prefix=REORDER +# RUN: llc -o - %s -mtriple=aarch64 -run-pass branch-folder -branch-folder-reorder-blocks=false -verify-machineinstrs | FileCheck %s --check-prefix=NOREORDER + +# Check that -branch-folder-reorder-blocks=false disables the basic-block +# reordering sub-phase of branch optimization. bb.1 is a non-fall-through return +# block sitting between the conditional branch in bb.0 and its taken target bb.2. +# +# With reordering enabled (default) BranchFolding reverses the bb.0 condition +# (CBZX -> CBNZX) so it can fall through, and relocates the blocks. With +# reordering disabled the original layout (CBZX; bb.1 is the return block) is +# preserved. + +# REORDER-LABEL: name: func +# REORDER: bb.0: +# REORDER: CBNZX $x1, %bb.2 +# REORDER: bb.1: +# REORDER: $x0 = ADDXri $x0, 1, 0 +# REORDER: $x0 = ADDXri $x0, 2, 0 +# REORDER: bb.2: +# REORDER-NOT: ADDXri +# REORDER: RET_ReallyLR implicit $x0 + +# NOREORDER-LABEL: name: func +# NOREORDER: bb.0: +# NOREORDER: CBZX $x1, %bb.2 +# NOREORDER: bb.1: +# NOREORDER: RET_ReallyLR implicit $x0 +# NOREORDER: bb.2: +# NOREORDER: $x0 = ADDXri $x0, 1, 0 +# NOREORDER: $x0 = ADDXri $x0, 2, 0 +# NOREORDER: RET_ReallyLR implicit $x0 + +name: func +tracksRegLiveness: true +body: | + bb.0: + successors: %bb.1, %bb.2 + liveins: $x0, $x1 + CBZX $x1, %bb.2 + + bb.1: + liveins: $x0 + RET_ReallyLR implicit $x0 + + bb.2: + successors: %bb.3 + liveins: $x0 + $x0 = ADDXri $x0, 1, 0 + B %bb.3 + + bb.3: + liveins: $x0 + $x0 = ADDXri $x0, 2, 0 + RET_ReallyLR implicit $x0 +... diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll index 68a6ab1d4d4f9..578bbf830344a 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll @@ -5,7 +5,7 @@ ; RUN: llc -global-isel=1 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 < %s | FileCheck -check-prefix=GFX1250 %s ; RUN: not llc -global-isel=0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s -; RUN: not llc -global-isel=1 -global-isel-abort=0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s +; RUN: not llc -global-isel=1 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s ; ERR: error: {{.*}}: in function {{@?}}v_permlane16_swap_b32_vv{{.*}}: llvm.amdgcn.permlane16.swap requires target feature 'permlane16-swap' diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll index 8579a2a9f64fc..08645068ac4cf 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,36 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sext_i32_i16 s6, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sext_i32_i16 s6, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -250,6 +282,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_add_i32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_add_i32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -504,6 +582,34 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -690,6 +796,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -952,6 +1098,34 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -1138,6 +1312,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1496,6 +1710,56 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX6DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX6DAGISEL-NEXT: s_add_u32 s8, s8, s13 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX6DAGISEL-NEXT: s_addc_u32 s9, s9, s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX7DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX7DAGISEL-NEXT: s_add_u32 s8, s8, s13 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX7DAGISEL-NEXT: s_addc_u32 s9, s9, s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2432,6 +2696,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2790,6 +3094,86 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s6, s2 +; GFX6DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s6, s2 +; GFX7DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -3338,16 +3722,60 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[4:5] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: s_mul_i32 s0, s2, s8 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s1, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s3, s8 +; GFX6DAGISEL-NEXT: s_add_u32 s1, s1, s2 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[4:5] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: s_mul_i32 s0, s2, s8 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s1, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s3, s8 +; GFX7DAGISEL-NEXT: s_add_u32 s1, s1, s2 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8DAGISEL-NEXT: s_mov_b64 s[4:5], exec ; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s4 ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v2, s2, v0 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s0 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s1 ; GFX8DAGISEL-NEXT: s_mul_i32 s0, s2, s4 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s1, s2, s4 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s1, v2 ; GFX8DAGISEL-NEXT: s_mul_i32 s2, s3, s4 ; GFX8DAGISEL-NEXT: s_add_u32 s1, s1, s2 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v3, s1 @@ -3359,15 +3787,17 @@ define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 ; GFX8GISEL: ; %bb.0: ; %entry ; GFX8GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8GISEL-NEXT: s_mov_b64 s[4:5], exec -; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s5, s[4:5] -; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s4, s2, s5 -; GFX8GISEL-NEXT: s_mul_hi_u32 s2, s2, s5 -; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s5 -; GFX8GISEL-NEXT: s_add_u32 s5, s2, s3 +; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] ; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s4 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX8GISEL-NEXT: s_mul_i32 s2, s2, s4 +; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s4 ; GFX8GISEL-NEXT: v_mov_b32_e32 v3, s1 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s4, v0 +; GFX8GISEL-NEXT: s_add_u32 s3, s4, s3 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s3 ; GFX8GISEL-NEXT: v_mov_b32_e32 v2, s0 ; GFX8GISEL-NEXT: flat_store_dwordx2 v[2:3], v[0:1] ; GFX8GISEL-NEXT: s_endpgm @@ -3555,6 +3985,56 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX6DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX6DAGISEL-NEXT: s_add_u32 s8, s8, s13 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX6DAGISEL-NEXT: s_addc_u32 s9, s9, s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX7DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX7DAGISEL-NEXT: s_add_u32 s8, s8, s13 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX7DAGISEL-NEXT: s_addc_u32 s9, s9, s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3832,6 +4312,94 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s6, s2, s7 +; GFX6DAGISEL-NEXT: s_mul_i32 s3, s3, s7 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 +; GFX6DAGISEL-NEXT: s_add_u32 s7, s2, s3 +; GFX6DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_4 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s7, v0 +; GFX6DAGISEL-NEXT: s_add_u32 s5, s7, s5 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: .LBB11_4: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s6, s2, s7 +; GFX7DAGISEL-NEXT: s_mul_i32 s3, s3, s7 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 +; GFX7DAGISEL-NEXT: s_add_u32 s7, s2, s3 +; GFX7DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_4 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s7, v0 +; GFX7DAGISEL-NEXT: s_add_u32 s5, s7, s5 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: .LBB11_4: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3844,10 +4412,12 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8DAGISEL-NEXT: ; %bb.1: ; %else ; GFX8DAGISEL-NEXT: s_mov_b64 s[6:7], exec ; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s7 ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 ; GFX8DAGISEL-NEXT: s_mul_i32 s6, s2, s7 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s2, s2, s7 ; GFX8DAGISEL-NEXT: s_mul_i32 s3, s3, s7 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 ; GFX8DAGISEL-NEXT: s_add_u32 s7, s2, s3 ; GFX8DAGISEL-NEXT: .LBB11_2: ; %Flow ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) @@ -3855,16 +4425,19 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s6 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s7 ; GFX8DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX8DAGISEL-NEXT: s_cbranch_execz .LBB11_4 ; GFX8DAGISEL-NEXT: ; %bb.3: ; %if ; GFX8DAGISEL-NEXT: s_mov_b64 s[6:7], exec -; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] -; GFX8DAGISEL-NEXT: s_mul_i32 s6, s4, s7 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s4, s4, s7 -; GFX8DAGISEL-NEXT: s_mul_i32 s5, s5, s7 -; GFX8DAGISEL-NEXT: s_add_u32 s7, s4, s5 +; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s7 -; GFX8DAGISEL-NEXT: ; %bb.4: ; %endif +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX8DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX8DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s7, v0 +; GFX8DAGISEL-NEXT: s_add_u32 s5, s7, s5 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX8DAGISEL-NEXT: .LBB11_4: ; %endif ; GFX8DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v2, s0 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v3, s1 @@ -3882,10 +4455,12 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8GISEL-NEXT: ; %bb.1: ; %else ; GFX8GISEL-NEXT: s_mov_b64 s[6:7], exec ; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s7 ; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s2, v0 ; GFX8GISEL-NEXT: s_mul_i32 s6, s2, s7 -; GFX8GISEL-NEXT: s_mul_hi_u32 s2, s2, s7 ; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s7 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s2, v0 ; GFX8GISEL-NEXT: s_add_u32 s7, s2, s3 ; GFX8GISEL-NEXT: .LBB11_2: ; %Flow ; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) @@ -3897,14 +4472,16 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8GISEL-NEXT: ; %bb.3: ; %if ; GFX8GISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0x34 ; GFX8GISEL-NEXT: s_mov_b64 s[6:7], exec -; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] -; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s6, s4, s7 -; GFX8GISEL-NEXT: s_mul_hi_u32 s4, s4, s7 -; GFX8GISEL-NEXT: s_mul_i32 s5, s5, s7 -; GFX8GISEL-NEXT: s_add_u32 s7, s4, s5 +; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] ; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX8GISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX8GISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s7, v0 +; GFX8GISEL-NEXT: s_add_u32 s5, s7, s5 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s5 ; GFX8GISEL-NEXT: .LBB11_4: ; %endif ; GFX8GISEL-NEXT: s_or_b64 exec, exec, s[2:3] ; GFX8GISEL-NEXT: v_mov_b32_e32 v3, s1 @@ -4382,6 +4959,32 @@ endif: } define amdgpu_kernel void @constant_value(ptr addrspace(1) %out) { +; GFX6DAGISEL-LABEL: constant_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, 0x10000 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: constant_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, 0x10000 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: constant_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll index 947b26df5a569..6b7d8ee27bd98 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, -1 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_and_b32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, -1 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_and_b32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -438,6 +510,28 @@ define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -550,6 +644,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -793,6 +927,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -905,6 +1061,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1238,6 +1434,54 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_and_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_and_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2090,6 +2334,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2423,6 +2707,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2888,6 +3244,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -2994,6 +3376,54 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_and_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_and_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3234,6 +3664,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll index 1a9e6f3a34475..132612c1f5e6f 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sext_i32_i16 s4, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sext_i32_i16 s4, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s10, 1 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_max_i32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s10, 1 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_max_i32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -400,6 +472,28 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -512,6 +606,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -755,6 +889,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -867,6 +1023,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1204,6 +1400,64 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s8, 0 +; GFX6DAGISEL-NEXT: s_brev_b32 s9, 1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_gt_i64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s8, 0 +; GFX7DAGISEL-NEXT: s_brev_b32 s9, 1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_gt_i64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2180,6 +2434,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2517,6 +2811,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2982,6 +3348,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3088,6 +3480,64 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s8, 0 +; GFX6DAGISEL-NEXT: s_brev_b32 s9, 1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_gt_i64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s8, 0 +; GFX7DAGISEL-NEXT: s_brev_b32 s9, 1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_gt_i64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3386,6 +3836,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll index 2c564bccf1678..c19059b754831 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sext_i32_i16 s4, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sext_i32_i16 s4, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s10, -2 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_min_i32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s10, -2 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_min_i32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -400,6 +472,28 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -512,6 +606,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -755,6 +889,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -867,6 +1023,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1204,6 +1400,64 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s8, -1 +; GFX6DAGISEL-NEXT: s_brev_b32 s9, -2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_lt_i64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s8, -1 +; GFX7DAGISEL-NEXT: s_brev_b32 s9, -2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_lt_i64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2180,6 +2434,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2517,6 +2811,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2982,6 +3348,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3088,6 +3480,64 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s8, -1 +; GFX6DAGISEL-NEXT: s_brev_b32 s9, -2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_lt_i64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s8, -1 +; GFX7DAGISEL-NEXT: s_brev_b32 s9, -2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_lt_i64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3386,6 +3836,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll index 1ae2a4268ff1e..740b83329ad44 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_or_b32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_or_b32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -438,6 +510,28 @@ define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -550,6 +644,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -793,6 +927,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -905,6 +1061,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1238,6 +1434,54 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2090,6 +2334,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2423,6 +2707,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2888,6 +3244,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -2994,6 +3376,54 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3235,6 +3665,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll index e5403a9a7d614..1f51a317cdc08 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,38 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sext_i32_i16 s6, s6 +; GFX6DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sext_i32_i16 s6, s6 +; GFX7DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -270,6 +304,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_sub_i32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_sub_i32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -524,6 +604,36 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -725,6 +835,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -987,6 +1137,36 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -1188,6 +1368,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1561,6 +1781,56 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX6DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX6DAGISEL-NEXT: s_sub_u32 s8, s8, s13 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX6DAGISEL-NEXT: s_subb_u32 s9, s9, s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX7DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX7DAGISEL-NEXT: s_sub_u32 s8, s8, s13 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX7DAGISEL-NEXT: s_subb_u32 s9, s9, s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2527,6 +2797,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2900,6 +3210,88 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sub_i32 s3, 0, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s3, s2 +; GFX6DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sub_i32 s3, 0, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s3, s2 +; GFX7DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -3461,19 +3853,71 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s0, s[8:9] +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: s_sub_i32 s1, 0, s0 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s1 +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX6DAGISEL-NEXT: s_ashr_i32 s0, s1, 31 +; GFX6DAGISEL-NEXT: s_mul_i32 s8, s2, s0 +; GFX6DAGISEL-NEXT: s_mul_i32 s0, s2, s1 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s1, s3, s1 +; GFX6DAGISEL-NEXT: s_add_u32 s1, s2, s1 +; GFX6DAGISEL-NEXT: s_add_u32 s1, s1, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s0, s[8:9] +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: s_sub_i32 s1, 0, s0 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s1 +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX7DAGISEL-NEXT: s_ashr_i32 s0, s1, 31 +; GFX7DAGISEL-NEXT: s_mul_i32 s8, s2, s0 +; GFX7DAGISEL-NEXT: s_mul_i32 s0, s2, s1 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s1, s3, s1 +; GFX7DAGISEL-NEXT: s_add_u32 s1, s2, s1 +; GFX7DAGISEL-NEXT: s_add_u32 s1, s1, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8DAGISEL-NEXT: s_mov_b64 s[4:5], exec ; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] ; GFX8DAGISEL-NEXT: s_sub_i32 s4, 0, s4 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v2, s4 ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v2, s2, v2 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s0 ; GFX8DAGISEL-NEXT: s_ashr_i32 s0, s4, 31 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s1 ; GFX8DAGISEL-NEXT: s_mul_i32 s1, s2, s0 ; GFX8DAGISEL-NEXT: s_mul_i32 s0, s2, s4 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s2, s2, s4 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s2, v2 ; GFX8DAGISEL-NEXT: s_mul_i32 s3, s3, s4 ; GFX8DAGISEL-NEXT: s_add_u32 s2, s2, s3 ; GFX8DAGISEL-NEXT: s_add_u32 s1, s2, s1 @@ -3487,17 +3931,19 @@ define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 ; GFX8GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8GISEL-NEXT: s_mov_b64 s[4:5], exec ; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] -; GFX8GISEL-NEXT: s_sub_i32 s5, 0, s4 -; GFX8GISEL-NEXT: s_ashr_i32 s4, s5, 31 -; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s6, s2, s4 -; GFX8GISEL-NEXT: s_mul_i32 s4, s2, s5 -; GFX8GISEL-NEXT: s_mul_hi_u32 s2, s2, s5 -; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s5 -; GFX8GISEL-NEXT: s_add_u32 s2, s2, s3 -; GFX8GISEL-NEXT: s_add_u32 s5, s2, s6 +; GFX8GISEL-NEXT: s_sub_i32 s4, 0, s4 ; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s4 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX8GISEL-NEXT: s_ashr_i32 s5, s4, 31 +; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s4 +; GFX8GISEL-NEXT: s_mul_i32 s5, s2, s5 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s6, v0 +; GFX8GISEL-NEXT: s_add_u32 s3, s6, s3 +; GFX8GISEL-NEXT: s_mul_i32 s2, s2, s4 +; GFX8GISEL-NEXT: s_add_u32 s3, s3, s5 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s3 ; GFX8GISEL-NEXT: v_mov_b32_e32 v3, s1 ; GFX8GISEL-NEXT: v_mov_b32_e32 v2, s0 ; GFX8GISEL-NEXT: flat_store_dwordx2 v[2:3], v[0:1] @@ -3735,6 +4181,56 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX6DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX6DAGISEL-NEXT: s_sub_u32 s8, s8, s13 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX6DAGISEL-NEXT: s_subb_u32 s9, s9, s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX7DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX7DAGISEL-NEXT: s_sub_u32 s8, s8, s13 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX7DAGISEL-NEXT: s_subb_u32 s9, s9, s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -4012,45 +4508,153 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr8_sgpr9 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[8:9] +; GFX6DAGISEL-NEXT: s_sub_i32 s9, 0, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s9 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX6DAGISEL-NEXT: s_ashr_i32 s10, s9, 31 +; GFX6DAGISEL-NEXT: s_mul_i32 s8, s2, s9 +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s2, s10 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s10, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s3, s3, s9 +; GFX6DAGISEL-NEXT: s_add_u32 s3, s10, s3 +; GFX6DAGISEL-NEXT: s_add_u32 s9, s3, s2 +; GFX6DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[6:7] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s9 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_4 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX6DAGISEL-NEXT: s_sub_i32 s7, 0, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX6DAGISEL-NEXT: s_ashr_i32 s8, s7, 31 +; GFX6DAGISEL-NEXT: s_mul_i32 s6, s4, s7 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, s8 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s8, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s5, s5, s7 +; GFX6DAGISEL-NEXT: s_add_u32 s5, s8, s5 +; GFX6DAGISEL-NEXT: s_add_u32 s7, s5, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX6DAGISEL-NEXT: .LBB11_4: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr8_sgpr9 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[8:9] +; GFX7DAGISEL-NEXT: s_sub_i32 s9, 0, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s9 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX7DAGISEL-NEXT: s_ashr_i32 s10, s9, 31 +; GFX7DAGISEL-NEXT: s_mul_i32 s8, s2, s9 +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s2, s10 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s10, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s3, s3, s9 +; GFX7DAGISEL-NEXT: s_add_u32 s3, s10, s3 +; GFX7DAGISEL-NEXT: s_add_u32 s9, s3, s2 +; GFX7DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[6:7] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s9 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_4 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX7DAGISEL-NEXT: s_sub_i32 s7, 0, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX7DAGISEL-NEXT: s_ashr_i32 s8, s7, 31 +; GFX7DAGISEL-NEXT: s_mul_i32 s6, s4, s7 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, s8 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s8, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s5, s5, s7 +; GFX7DAGISEL-NEXT: s_add_u32 s5, s8, s5 +; GFX7DAGISEL-NEXT: s_add_u32 s7, s5, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX7DAGISEL-NEXT: .LBB11_4: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0x34 ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 -; GFX8DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 -; GFX8DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc -; GFX8DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX8DAGISEL-NEXT: ; implicit-def: $sgpr8_sgpr9 +; GFX8DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX8DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] ; GFX8DAGISEL-NEXT: s_cbranch_execz .LBB11_2 ; GFX8DAGISEL-NEXT: ; %bb.1: ; %else -; GFX8DAGISEL-NEXT: s_mov_b64 s[6:7], exec -; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] -; GFX8DAGISEL-NEXT: s_sub_i32 s7, 0, s6 -; GFX8DAGISEL-NEXT: s_ashr_i32 s6, s7, 31 +; GFX8DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[8:9] +; GFX8DAGISEL-NEXT: s_sub_i32 s9, 0, s8 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s9 ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8DAGISEL-NEXT: s_mul_i32 s10, s2, s6 -; GFX8DAGISEL-NEXT: s_mul_i32 s6, s2, s7 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s2, s2, s7 -; GFX8DAGISEL-NEXT: s_mul_i32 s3, s3, s7 -; GFX8DAGISEL-NEXT: s_add_u32 s2, s2, s3 -; GFX8DAGISEL-NEXT: s_add_u32 s7, s2, s10 +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX8DAGISEL-NEXT: s_ashr_i32 s10, s9, 31 +; GFX8DAGISEL-NEXT: s_mul_i32 s8, s2, s9 +; GFX8DAGISEL-NEXT: s_mul_i32 s2, s2, s10 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s10, v0 +; GFX8DAGISEL-NEXT: s_mul_i32 s3, s3, s9 +; GFX8DAGISEL-NEXT: s_add_u32 s3, s10, s3 +; GFX8DAGISEL-NEXT: s_add_u32 s9, s3, s2 ; GFX8DAGISEL-NEXT: .LBB11_2: ; %Flow ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] -; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX8DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[6:7] +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s9 ; GFX8DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] ; GFX8DAGISEL-NEXT: s_cbranch_execz .LBB11_4 ; GFX8DAGISEL-NEXT: ; %bb.3: ; %if ; GFX8DAGISEL-NEXT: s_mov_b64 s[6:7], exec ; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] ; GFX8DAGISEL-NEXT: s_sub_i32 s7, 0, s6 -; GFX8DAGISEL-NEXT: s_ashr_i32 s6, s7, 31 -; GFX8DAGISEL-NEXT: s_mul_i32 s8, s4, s6 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX8DAGISEL-NEXT: s_ashr_i32 s8, s7, 31 ; GFX8DAGISEL-NEXT: s_mul_i32 s6, s4, s7 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s4, s4, s7 +; GFX8DAGISEL-NEXT: s_mul_i32 s4, s4, s8 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s8, v0 ; GFX8DAGISEL-NEXT: s_mul_i32 s5, s5, s7 -; GFX8DAGISEL-NEXT: s_add_u32 s4, s4, s5 -; GFX8DAGISEL-NEXT: s_add_u32 s7, s4, s8 +; GFX8DAGISEL-NEXT: s_add_u32 s5, s8, s5 +; GFX8DAGISEL-NEXT: s_add_u32 s7, s5, s4 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s6 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s7 ; GFX8DAGISEL-NEXT: .LBB11_4: ; %endif @@ -4064,44 +4668,48 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8GISEL: ; %bb.0: ; %entry ; GFX8GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8GISEL-NEXT: v_cmp_le_u32_e32 vcc, 16, v0 -; GFX8GISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 -; GFX8GISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc -; GFX8GISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX8GISEL-NEXT: ; implicit-def: $sgpr8_sgpr9 +; GFX8GISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX8GISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] ; GFX8GISEL-NEXT: s_cbranch_execz .LBB11_2 ; GFX8GISEL-NEXT: ; %bb.1: ; %else -; GFX8GISEL-NEXT: s_mov_b64 s[6:7], exec -; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] -; GFX8GISEL-NEXT: s_sub_i32 s7, 0, s6 -; GFX8GISEL-NEXT: s_ashr_i32 s6, s7, 31 +; GFX8GISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s8, s[8:9] +; GFX8GISEL-NEXT: s_sub_i32 s9, 0, s8 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s9 ; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s10, s2, s6 -; GFX8GISEL-NEXT: s_mul_i32 s6, s2, s7 -; GFX8GISEL-NEXT: s_mul_hi_u32 s2, s2, s7 -; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s7 -; GFX8GISEL-NEXT: s_add_u32 s2, s2, s3 -; GFX8GISEL-NEXT: s_add_u32 s7, s2, s10 +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX8GISEL-NEXT: s_ashr_i32 s10, s9, 31 +; GFX8GISEL-NEXT: s_mul_i32 s8, s2, s9 +; GFX8GISEL-NEXT: s_mul_i32 s2, s2, s10 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s10, v0 +; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s9 +; GFX8GISEL-NEXT: s_add_u32 s3, s10, s3 +; GFX8GISEL-NEXT: s_add_u32 s9, s3, s2 ; GFX8GISEL-NEXT: .LBB11_2: ; %Flow ; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] -; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX8GISEL-NEXT: s_or_saveexec_b64 s[2:3], s[6:7] +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s9 ; GFX8GISEL-NEXT: s_xor_b64 exec, exec, s[2:3] ; GFX8GISEL-NEXT: s_cbranch_execz .LBB11_4 ; GFX8GISEL-NEXT: ; %bb.3: ; %if ; GFX8GISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0x34 ; GFX8GISEL-NEXT: s_mov_b64 s[6:7], exec ; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] -; GFX8GISEL-NEXT: s_sub_i32 s7, 0, s6 -; GFX8GISEL-NEXT: s_ashr_i32 s6, s7, 31 -; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s8, s4, s6 -; GFX8GISEL-NEXT: s_mul_i32 s6, s4, s7 -; GFX8GISEL-NEXT: s_mul_hi_u32 s4, s4, s7 -; GFX8GISEL-NEXT: s_mul_i32 s5, s5, s7 -; GFX8GISEL-NEXT: s_add_u32 s4, s4, s5 -; GFX8GISEL-NEXT: s_add_u32 s7, s4, s8 +; GFX8GISEL-NEXT: s_sub_i32 s6, 0, s6 ; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX8GISEL-NEXT: s_ashr_i32 s7, s6, 31 +; GFX8GISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX8GISEL-NEXT: s_mul_i32 s7, s4, s7 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s8, v0 +; GFX8GISEL-NEXT: s_add_u32 s5, s8, s5 +; GFX8GISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX8GISEL-NEXT: s_add_u32 s5, s5, s7 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s5 ; GFX8GISEL-NEXT: .LBB11_4: ; %endif ; GFX8GISEL-NEXT: s_or_b64 exec, exec, s[2:3] ; GFX8GISEL-NEXT: v_mov_b32_e32 v3, s1 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll index 4d5bd7c29417a..1684aa599344d 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -182,6 +208,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_max_u32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_max_u32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -450,6 +522,28 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -562,6 +656,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -805,6 +939,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -917,6 +1073,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1250,6 +1446,62 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_gt_u64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_gt_u64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2186,6 +2438,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2519,6 +2811,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2984,6 +3348,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3090,6 +3480,28 @@ entry: } define amdgpu_kernel void @const_value_i64(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: const_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, 0x7b +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, 0 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: const_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, 0x7b +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, 0 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: const_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -3192,6 +3604,14 @@ entry: } define amdgpu_kernel void @poison_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: poison_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: poison_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: poison_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_endpgm @@ -3244,6 +3664,62 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB12_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_gt_u64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB12_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB12_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_gt_u64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB12_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3530,6 +4006,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll index e787784a656ee..29d45ce160a71 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, -1 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_min_u32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, -1 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_min_u32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -438,6 +510,28 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -550,6 +644,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -793,6 +927,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -905,6 +1061,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1238,6 +1434,62 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_lt_u64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_lt_u64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2174,6 +2426,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2507,6 +2799,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2972,6 +3336,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3078,6 +3468,62 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_lt_u64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_lt_u64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3364,6 +3810,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll index 84bb41ad62c57..77d89e18dbadd 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,38 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, 0xffff +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, 0xffff +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -256,6 +290,52 @@ define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_xor_b32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_xor_b32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -524,6 +604,36 @@ define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -712,6 +822,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -955,6 +1105,36 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -1143,6 +1323,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1476,6 +1696,54 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_xor_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_xor_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2328,6 +2596,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2661,6 +2969,88 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX6DAGISEL-NEXT: s_and_b32 s2, s2, 1 +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s6, s2 +; GFX6DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX7DAGISEL-NEXT: s_and_b32 s2, s2, 1 +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s6, s2 +; GFX7DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -3178,6 +3568,42 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s0, s[8:9] +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: s_and_b32 s1, s0, 1 +; GFX6DAGISEL-NEXT: s_mul_i32 s0, s2, s1 +; GFX6DAGISEL-NEXT: s_mul_i32 s1, s3, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s0, s[8:9] +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: s_and_b32 s1, s0, 1 +; GFX7DAGISEL-NEXT: s_mul_i32 s0, s2, s1 +; GFX7DAGISEL-NEXT: s_mul_i32 s1, s3, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3369,6 +3795,54 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_xor_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_xor_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3609,6 +4083,80 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX6DAGISEL-NEXT: s_and_b32 s7, s6, 1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s6, s2, s7 +; GFX6DAGISEL-NEXT: s_mul_i32 s7, s3, s7 +; GFX6DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, 1 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.4: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX7DAGISEL-NEXT: s_and_b32 s7, s6, 1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s6, s2, s7 +; GFX7DAGISEL-NEXT: s_mul_i32 s7, s3, s7 +; GFX7DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, 1 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.4: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -4094,6 +4642,34 @@ endif: } define amdgpu_kernel void @constant_value(ptr addrspace(1) %out) { +; GFX6DAGISEL-LABEL: constant_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, 30 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: constant_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, 30 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: constant_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll new file mode 100644 index 0000000000000..5a35d603e9703 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll @@ -0,0 +1,349 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-rewrite-out-arguments < %s | FileCheck %s + +define i32 @load_out_ptr_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define i32 @load_out_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + store i32 0, ptr addrspace(5) %out + %load = load i32, ptr addrspace(5) %out + ret i32 %load +} + +define i32 @load_out_ptr_before_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define i32 @load_out_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + %load = load i32, ptr addrspace(5) %out + store i32 0, ptr addrspace(5) %out + ret i32 %load +} + +define i32 @volatile_load_out_ptr_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define i32 @volatile_load_out_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + store i32 0, ptr addrspace(5) %out + %load = load volatile i32, ptr addrspace(5) %out + ret i32 %load +} + +define i32 @atomic_load_out_ptr_before_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define i32 @atomic_load_out_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: [[LOAD:%.*]] = load atomic i32, ptr addrspace(5) [[OUT]] monotonic, align 4 +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + %load = load atomic i32, ptr addrspace(5) %out monotonic, align 4 + store i32 0, ptr addrspace(5) %out + ret i32 %load +} + +define void @volatile_store_out_ptr(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @volatile_store_out_ptr( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store volatile i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret void +; + store volatile i32 0, ptr addrspace(5) %out + ret void +} + +define void @atomic_store_out_ptr(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @atomic_store_out_ptr( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store atomic i32 0, ptr addrspace(5) [[OUT]] monotonic, align 4 +; CHECK-NEXT: ret void +; + store atomic i32 0, ptr addrspace(5) %out monotonic, align 4 + ret void +} + +define void @atomic_store_out_ptr_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @atomic_store_out_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[OUT]] release, align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store atomic i32 1, ptr addrspace(5) %out release, align 4 + ret void +} + +define i32 @load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @load_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[LOAD_PTR_AFTER_STORE:%.*]] @[[LOAD_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[LOAD_PTR_AFTER_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[LOAD_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + store i32 0, ptr addrspace(5) %out + %load = load i32, ptr addrspace(5) %ptr + ret i32 %load +} + +define i32 @volatile_load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @volatile_load_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[VOLATILE_LOAD_PTR_AFTER_STORE:%.*]] @[[VOLATILE_LOAD_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_AFTER_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + store i32 0, ptr addrspace(5) %out + %load = load volatile i32, ptr addrspace(5) %ptr + ret i32 %load +} + +define i32 @atomic_load_acquire_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @atomic_load_acquire_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: [[LOAD:%.*]] = load atomic i32, ptr addrspace(5) [[PTR]] acquire, align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + store i32 0, ptr addrspace(5) %out + %load = load atomic i32, ptr addrspace(5) %ptr acquire, align 4 + ret i32 %load +} + +define i32 @atomic_load_monotonic_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @atomic_load_monotonic_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE:%.*]] @[[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + store i32 0, ptr addrspace(5) %out + %load = load atomic i32, ptr addrspace(5) %ptr monotonic, align 4 + ret i32 %load +} + +define void @volatile_store_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @volatile_store_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store volatile i32 1, ptr addrspace(5) [[PTR]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store volatile i32 1, ptr addrspace(5) %ptr + ret void +} + +define void @atomic_store_release_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @atomic_store_release_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[PTR]] release, align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store atomic i32 1, ptr addrspace(5) %ptr release, align 4 + ret void +} + +define void @atomic_store_unordered_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @atomic_store_unordered_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[PTR]] unordered, align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store atomic i32 1, ptr addrspace(5) %ptr unordered, align 4 + ret void +} + +define void @opaque_read_call_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @opaque_read_call_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP2:%.*]] = call [[OPAQUE_READ_CALL_AFTER_STORE:%.*]] @[[OPAQUE_READ_CALL_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison) +; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[OPAQUE_READ_CALL_AFTER_STORE]] [[TMP2]], 0 +; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @opaque_read() + ret void +} + +define void @opaque_rw_call_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @opaque_rw_call_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: call void @opaque_rw_argmem(ptr addrspace(5) [[PTR]]) +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @opaque_rw_argmem(ptr addrspace(5) %ptr) + ret void +} + +define void @opaque_call_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @opaque_call_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: call void @opaque() +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @opaque() + ret void +} + +define void @memcpy_after_store(ptr addrspace(5) %out, ptr addrspace(5) %src, ptr addrspace(5) noalias %dst) { +; CHECK-LABEL: define void @memcpy_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]], ptr addrspace(5) noalias [[TMP2:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP4:%.*]] = call [[MEMCPY_AFTER_STORE:%.*]] @[[MEMCPY_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[TMP2]]) +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[MEMCPY_AFTER_STORE]] [[TMP4]], 0 +; CHECK-NEXT: store i32 [[TMP5]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) %dst, ptr addrspace(5) %src, i32 4, i1 false) + ret void +} + +define void @memset_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @memset_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: call void @llvm.memset.p5.i32(ptr addrspace(5) [[PTR]], i8 0, i32 4, i1 false) +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @llvm.memset.p5.i32(ptr addrspace(5) %ptr, i8 0, i32 4, i1 false) + ret void +} + +define void @memset_noalias_ptr_after_store(ptr addrspace(5) noalias %out, ptr addrspace(5) noalias %ptr) { +; CHECK-LABEL: define void @memset_noalias_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) noalias [[TMP0:%.*]], ptr addrspace(5) noalias [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[MEMSET_NOALIAS_PTR_AFTER_STORE:%.*]] @[[MEMSET_NOALIAS_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[MEMSET_NOALIAS_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @llvm.memset.p5.i32(ptr addrspace(5) %ptr, i8 0, i32 4, i1 false) + ret void +} + +define i32 @load_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @load_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[LOAD_PTR_BEFORE_STORE:%.*]] @[[LOAD_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[LOAD_PTR_BEFORE_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[LOAD_PTR_BEFORE_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + %load = load i32, ptr addrspace(5) %ptr + store i32 0, ptr addrspace(5) %out + ret i32 %load +} + +define i32 @volatile_load_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @volatile_load_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[VOLATILE_LOAD_PTR_BEFORE_STORE:%.*]] @[[VOLATILE_LOAD_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_BEFORE_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_BEFORE_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + %load = load volatile i32, ptr addrspace(5) %ptr + store i32 0, ptr addrspace(5) %out + ret i32 %load +} + +define void @atomic_store_release_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @atomic_store_release_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE:%.*]] @[[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE]] [[TMP3]], 0 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store atomic i32 1, ptr addrspace(5) %ptr release, align 4 + store i32 0, ptr addrspace(5) %out + ret void +} + +define void @atomic_store_seq_cst_noalias_ptr_after_store(ptr addrspace(5) noalias %out, ptr addrspace(5) noalias %ptr) { +; CHECK-LABEL: define void @atomic_store_seq_cst_noalias_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) noalias [[TMP0:%.*]], ptr addrspace(5) noalias [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE:%.*]] @[[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store atomic i32 1, ptr addrspace(5) %ptr seq_cst, align 4 + ret void +} + +define void @fence_release_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @fence_release_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP2:%.*]] = call [[FENCE_RELEASE_AFTER_STORE:%.*]] @[[FENCE_RELEASE_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison) +; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[FENCE_RELEASE_AFTER_STORE]] [[TMP2]], 0 +; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + fence release + ret void +} + +define void @fence_seq_cst_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @fence_seq_cst_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: fence seq_cst +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + fence seq_cst + ret void +} + +define void @store_cross_bb(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @store_cross_bb( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: br label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + store i32 0, ptr addrspace(5) %out + br label %exit + +exit: + ret void +} + +declare void @opaque_read() memory(read) +declare void @opaque() +declare void @opaque_rw_argmem(ptr addrspace(5)) memory(argmem: readwrite) +declare void @llvm.memcpy.p5.p5.i32(ptr addrspace(5), ptr addrspace(5), i32, i1) +declare void @llvm.memset.p5.i32(ptr addrspace(5), i8, i32, i1) diff --git a/llvm/test/CodeGen/AMDGPU/strict_fptrunc_bf16.ll b/llvm/test/CodeGen/AMDGPU/strict_fptrunc_bf16.ll new file mode 100644 index 0000000000000..1aa8815e63868 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/strict_fptrunc_bf16.ll @@ -0,0 +1,151 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=amdgcn -mcpu=gfx950 < %s | FileCheck --check-prefixes=GFX950 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1250 -mattr=-real-true16 < %s | FileCheck --check-prefixes=GFX1250 %s + +define amdgpu_ps void @strict_fptrunc_f32_to_bf16(float %a, ptr %out) #0 { +; GFX950-LABEL: strict_fptrunc_f32_to_bf16: +; GFX950: ; %bb.0: +; GFX950-NEXT: v_mov_b32_e32 v3, v2 +; GFX950-NEXT: v_mov_b32_e32 v2, v1 +; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0 +; GFX950-NEXT: flat_store_short v[2:3], v0 +; GFX950-NEXT: s_endpgm +; +; GFX1250-LABEL: strict_fptrunc_f32_to_bf16: +; GFX1250: ; %bb.0: +; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0 +; GFX1250-NEXT: v_dual_mov_b32 v3, v2 :: v_dual_mov_b32 v2, v1 +; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0 +; GFX1250-NEXT: flat_store_b16 v[2:3], v0 +; GFX1250-NEXT: s_endpgm + %cvt = call bfloat @llvm.experimental.constrained.fptrunc.bf16.f32(float %a, metadata !"round.tonearest", metadata !"fpexcept.strict") + store bfloat %cvt, ptr %out + ret void +} + +define amdgpu_ps void @strict_fptrunc_f64_to_bf16(double %a, ptr %out) #0 { +; GFX950-LABEL: strict_fptrunc_f64_to_bf16: +; GFX950: ; %bb.0: +; GFX950-NEXT: v_cvt_f32_f64_e32 v6, v[0:1] +; GFX950-NEXT: v_cvt_f64_f32_e32 v[4:5], v6 +; GFX950-NEXT: v_and_b32_e32 v7, 1, v6 +; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, |v[4:5]| +; GFX950-NEXT: v_cmp_nlg_f64_e32 vcc, v[0:1], v[4:5] +; GFX950-NEXT: v_cmp_eq_u32_e64 s[0:1], 1, v7 +; GFX950-NEXT: v_cndmask_b32_e64 v0, -1, 1, s[2:3] +; GFX950-NEXT: v_add_u32_e32 v0, v6, v0 +; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1] +; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v6, vcc +; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0 +; GFX950-NEXT: flat_store_short v[2:3], v0 +; GFX950-NEXT: s_endpgm +; +; GFX1250-LABEL: strict_fptrunc_f64_to_bf16: +; GFX1250: ; %bb.0: +; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0 +; GFX1250-NEXT: v_cvt_f32_f64_e32 v6, v[0:1] +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1) +; GFX1250-NEXT: v_cvt_f64_f32_e32 v[4:5], v6 +; GFX1250-NEXT: v_cmp_gt_f64_e64 s0, |v[0:1]|, |v[4:5]| +; GFX1250-NEXT: v_cmp_nlg_f64_e32 vcc_lo, v[0:1], v[4:5] +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1) +; GFX1250-NEXT: v_cndmask_b32_e64 v0, -1, 1, s0 +; GFX1250-NEXT: v_dual_add_nc_u32 v0, v6, v0 :: v_dual_bitop2_b32 v7, 1, v6 bitop3:0x40 +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1) +; GFX1250-NEXT: v_cmp_eq_u32_e64 s0, 1, v7 +; GFX1250-NEXT: s_or_b32 vcc_lo, vcc_lo, s0 +; GFX1250-NEXT: v_cndmask_b32_e32 v0, v0, v6, vcc_lo +; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0 +; GFX1250-NEXT: flat_store_b16 v[2:3], v0 +; GFX1250-NEXT: s_endpgm + %cvt = call bfloat @llvm.experimental.constrained.fptrunc.bf16.f64(double %a, metadata !"round.tonearest", metadata !"fpexcept.strict") + store bfloat %cvt, ptr %out + ret void +} + +define amdgpu_ps void @strict_fptrunc_v2f32_to_v2bf16(<2 x float> %a, ptr %out) #0 { +; GFX950-LABEL: strict_fptrunc_v2f32_to_v2bf16: +; GFX950: ; %bb.0: +; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1 +; GFX950-NEXT: flat_store_dword v[2:3], v0 +; GFX950-NEXT: s_endpgm +; +; GFX1250-LABEL: strict_fptrunc_v2f32_to_v2bf16: +; GFX1250: ; %bb.0: +; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0 +; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1 +; GFX1250-NEXT: flat_store_b32 v[2:3], v0 +; GFX1250-NEXT: s_endpgm + %cvt = call <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f32(<2 x float> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") + store <2 x bfloat> %cvt, ptr %out + ret void +} + +define amdgpu_ps void @strict_fptrunc_v2f64_to_v2bf16(<2 x double> %a, ptr %out) #0 { +; GFX950-LABEL: strict_fptrunc_v2f64_to_v2bf16: +; GFX950: ; %bb.0: +; GFX950-NEXT: v_cvt_f32_f64_e32 v8, v[2:3] +; GFX950-NEXT: v_and_b32_e32 v6, 1, v8 +; GFX950-NEXT: v_cmp_ne_u32_e32 vcc, 0, v6 +; GFX950-NEXT: v_cvt_f64_f32_e32 v[6:7], v8 +; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[2:3]|, |v[6:7]| +; GFX950-NEXT: v_cmp_nlg_f64_e64 s[0:1], v[2:3], v[6:7] +; GFX950-NEXT: v_cvt_f32_f64_e32 v9, v[0:1] +; GFX950-NEXT: v_cndmask_b32_e64 v2, -1, 1, s[2:3] +; GFX950-NEXT: v_add_u32_e32 v2, v8, v2 +; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1] +; GFX950-NEXT: v_cndmask_b32_e32 v6, v2, v8, vcc +; GFX950-NEXT: v_cvt_f64_f32_e32 v[2:3], v9 +; GFX950-NEXT: v_and_b32_e32 v10, 1, v9 +; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, |v[2:3]| +; GFX950-NEXT: v_cmp_ne_u32_e32 vcc, 0, v10 +; GFX950-NEXT: v_cmp_nlg_f64_e64 s[0:1], v[0:1], v[2:3] +; GFX950-NEXT: v_cndmask_b32_e64 v0, -1, 1, s[2:3] +; GFX950-NEXT: v_add_u32_e32 v0, v9, v0 +; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1] +; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v9, vcc +; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, v6 +; GFX950-NEXT: flat_store_dword v[4:5], v0 +; GFX950-NEXT: s_endpgm +; +; GFX1250-LABEL: strict_fptrunc_v2f64_to_v2bf16: +; GFX1250: ; %bb.0: +; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0 +; GFX1250-NEXT: v_cvt_f32_f64_e32 v10, v[2:3] +; GFX1250-NEXT: v_cvt_f32_f64_e32 v11, v[0:1] +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2) +; GFX1250-NEXT: v_cvt_f64_f32_e32 v[6:7], v10 +; GFX1250-NEXT: v_cvt_f64_f32_e32 v[8:9], v11 +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_3) +; GFX1250-NEXT: v_cmp_gt_f64_e64 s1, |v[2:3]|, |v[6:7]| +; GFX1250-NEXT: v_cmp_nlg_f64_e32 vcc_lo, v[2:3], v[6:7] +; GFX1250-NEXT: v_cmp_nlg_f64_e64 s0, v[0:1], v[8:9] +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2) +; GFX1250-NEXT: v_cndmask_b32_e64 v2, -1, 1, s1 +; GFX1250-NEXT: v_cmp_gt_f64_e64 s1, |v[0:1]|, |v[8:9]| +; GFX1250-NEXT: v_dual_add_nc_u32 v1, v10, v2 :: v_dual_bitop2_b32 v13, 1, v11 bitop3:0x40 +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_3) +; GFX1250-NEXT: v_cmp_ne_u32_e64 s2, 0, v13 +; GFX1250-NEXT: v_cndmask_b32_e64 v0, -1, 1, s1 +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1) +; GFX1250-NEXT: v_dual_add_nc_u32 v0, v11, v0 :: v_dual_bitop2_b32 v12, 1, v10 bitop3:0x40 +; GFX1250-NEXT: v_cmp_ne_u32_e64 s1, 0, v12 +; GFX1250-NEXT: s_or_b32 vcc_lo, s1, vcc_lo +; GFX1250-NEXT: v_cndmask_b32_e32 v1, v1, v10, vcc_lo +; GFX1250-NEXT: s_or_b32 vcc_lo, s2, s0 +; GFX1250-NEXT: v_cndmask_b32_e32 v0, v0, v11, vcc_lo +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) +; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1 +; GFX1250-NEXT: flat_store_b32 v[4:5], v0 +; GFX1250-NEXT: s_endpgm + %cvt = call <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f64(<2 x double> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") + store <2 x bfloat> %cvt, ptr %out + ret void +} + +declare bfloat @llvm.experimental.constrained.fptrunc.bf16.f32(float, metadata, metadata) +declare bfloat @llvm.experimental.constrained.fptrunc.bf16.f64(double, metadata, metadata) +declare <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f32(<2 x float>, metadata, metadata) +declare <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f64(<2 x double>, metadata, metadata) + +attributes #0 = { strictfp } diff --git a/llvm/test/CodeGen/AMDGPU/target-cpu.ll b/llvm/test/CodeGen/AMDGPU/target-cpu.ll index 2e6a3aee4be63..994319756db77 100644 --- a/llvm/test/CodeGen/AMDGPU/target-cpu.ll +++ b/llvm/test/CodeGen/AMDGPU/target-cpu.ll @@ -1,80 +1,58 @@ -; RUN: llc -mtriple=amdgcn -mcpu=gfx600 -disable-promote-alloca-to-vector < %s | FileCheck %s - -declare ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() #1 - -declare i32 @llvm.amdgcn.workitem.id.x() #1 - -; CI+ intrinsic -declare void @llvm.amdgcn.s.dcache.inv.vol() #0 - -; VI+ intrinsic -declare void @llvm.amdgcn.s.dcache.wb() #0 +; RUN: llc -mtriple=amdgpu9 < %s | FileCheck %s +; The default gfx9-generic subtarget lacks the mad-mix instructions, so the +; f16 multiply-add is expanded to conversions plus a separate fma. ; CHECK-LABEL: {{^}}target_none: -; CHECK: s_movk_i32 [[OFFSETREG:s[0-9]+]], 0x400 -; CHECK: s_load_dwordx2 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, [[OFFSETREG]] -; CHECK: buffer_store_dword v{{[0-9]+}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0 addr64 -define amdgpu_kernel void @target_none() #0 { - %kernargs = call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() - %kernargs.gep = getelementptr inbounds i8, ptr addrspace(4) %kernargs, i64 1024 - %ptr = load ptr addrspace(1), ptr addrspace(4) %kernargs.gep - %id = call i32 @llvm.amdgcn.workitem.id.x() - %id.ext = sext i32 %id to i64 - %gep = getelementptr inbounds i32, ptr addrspace(1) %ptr, i64 %id.ext - store i32 0, ptr addrspace(1) %gep - ret void +; CHECK: v_cvt_f32_f16_e32 [[A:v[0-9]+]], v0 +; CHECK: v_cvt_f32_f16_e32 [[B:v[0-9]+]], v1 +; CHECK: v_cvt_f32_f16_e32 [[C:v[0-9]+]], v2 +; CHECK: v_mac_f32_e32 [[C]], [[A]], [[B]] +define float @target_none(half %a, half %b, half %c) #1 { + %ae = fpext half %a to float + %be = fpext half %b to float + %ce = fpext half %c to float + %r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce) + ret float %r } -; CHECK-LABEL: {{^}}target_tahiti: -; CHECK: s_movk_i32 [[OFFSETREG:s[0-9]+]], 0x400 -; CHECK: s_load_dwordx2 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, [[OFFSETREG]] -; CHECK: buffer_store_dword v{{[0-9]+}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0 addr64 -define amdgpu_kernel void @target_tahiti() #1 { - %kernargs = call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() - %kernargs.gep = getelementptr inbounds i8, ptr addrspace(4) %kernargs, i64 1024 - %ptr = load ptr addrspace(1), ptr addrspace(4) %kernargs.gep - %id = call i32 @llvm.amdgcn.workitem.id.x() - %id.ext = sext i32 %id to i64 - %gep = getelementptr inbounds i32, ptr addrspace(1) %ptr, i64 %id.ext - store i32 0, ptr addrspace(1) %gep - ret void +; gfx900 has the mad-mix instructions, so the same multiply-add folds the f16 +; conversions into a single v_mad_mix_f32. +; CHECK-LABEL: {{^}}target_gfx900: +; CHECK: v_mad_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,1] +define float @target_gfx900(half %a, half %b, half %c) #2 { + %ae = fpext half %a to float + %be = fpext half %b to float + %ce = fpext half %c to float + %r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce) + ret float %r } -; CHECK-LABEL: {{^}}target_bonaire: -; CHECK: s_load_dwordx2 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0x100 -; CHECK: buffer_store_dword v{{[0-9]+}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0 addr64 -; CHECK: s_dcache_inv_vol -define amdgpu_kernel void @target_bonaire() #3 { - %kernargs = call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() - %kernargs.gep = getelementptr inbounds i8, ptr addrspace(4) %kernargs, i64 1024 - %ptr = load ptr addrspace(1), ptr addrspace(4) %kernargs.gep - %id = call i32 @llvm.amdgcn.workitem.id.x() - %id.ext = sext i32 %id to i64 - %gep = getelementptr inbounds i32, ptr addrspace(1) %ptr, i64 %id.ext - store i32 0, ptr addrspace(1) %gep - call void @llvm.amdgcn.s.dcache.inv.vol() - ret void +; gfx906 has the fma-mix instructions, so the same multiply-add folds the f16 +; conversions into a single v_fma_mix_f32. +; CHECK-LABEL: {{^}}target_gfx906_mad_mix: +; CHECK: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,1] +define float @target_gfx906_mad_mix(half %a, half %b, half %c) #4 { + %ae = fpext half %a to float + %be = fpext half %b to float + %ce = fpext half %c to float + %r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce) + ret float %r } -; CHECK-LABEL: {{^}}target_fiji: -; CHECK: s_load_dwordx2 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0x400 -; CHECK: flat_store_dword -; CHECK: s_dcache_wb{{$}} -define amdgpu_kernel void @target_fiji() #4 { - %kernargs = call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() - %kernargs.gep = getelementptr inbounds i8, ptr addrspace(4) %kernargs, i64 1024 - %ptr = load ptr addrspace(1), ptr addrspace(4) %kernargs.gep - %id = call i32 @llvm.amdgcn.workitem.id.x() - %id.ext = sext i32 %id to i64 - %gep = getelementptr inbounds i32, ptr addrspace(1) %ptr, i64 %id.ext - store i32 0, ptr addrspace(1) %gep - call void @llvm.amdgcn.s.dcache.wb() +; The fdot2 intrinsic is only available on gfx906. +; CHECK-LABEL: {{^}}target_gfx906: +; CHECK: v_dot2_f32_f16 +define amdgpu_kernel void @target_gfx906(ptr addrspace(1) %out, <2 x half> %a, <2 x half> %b, float %c) #3 { + %dot = call float @llvm.amdgcn.fdot2(<2 x half> %a, <2 x half> %b, float %c, i1 false) + store float %dot, ptr addrspace(1) %out, align 4 ret void } -attributes #0 = { nounwind } -attributes #1 = { nounwind readnone } -attributes #2 = { nounwind "target-cpu"="tahiti" } -attributes #3 = { nounwind "target-cpu"="bonaire" } -attributes #4 = { nounwind "target-cpu"="fiji" } -attributes #5 = { nounwind "amdgpu-waves-per-eu"="1,3" "amdgpu-flat-work-group-size"="1,256" } +declare float @llvm.fmuladd.f32(float, float, float) #0 +declare float @llvm.amdgcn.fdot2(<2 x half>, <2 x half>, float, i1 immarg) #0 + +attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +attributes #1 = { nounwind denormal_fpenv(float: preservesign) } +attributes #2 = { nounwind denormal_fpenv(float: preservesign) "target-cpu"="gfx900" } +attributes #3 = { nounwind "target-cpu"="gfx906" } +attributes #4 = { nounwind denormal_fpenv(float: preservesign) "target-cpu"="gfx906" } diff --git a/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir b/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir new file mode 100644 index 0000000000000..6a83fec35fba2 --- /dev/null +++ b/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir @@ -0,0 +1,44 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 +# RUN: llc -mtriple=bpfel -mattr=+alu32 -run-pass=bpf-mi-zext-elim -verify-machineinstrs %s -o - | FileCheck %s +... + +# Make sure that folds of MOV_32_64 respect a subregister index on the +# source operand. + +--- +name: mov32_64_subreg_source_imm +tracksRegLiveness: true +body: | + bb.0: + liveins: $r1 + ; CHECK-LABEL: name: mov32_64_subreg_source_imm + ; CHECK: liveins: $r1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LD_imm64_:%[0-9]+]]:gpr = LD_imm64 0 + ; CHECK-NEXT: [[MOV_32_64_:%[0-9]+]]:gpr = MOV_32_64 [[LD_imm64_]].sub_32 + ; CHECK-NEXT: $r0 = COPY [[MOV_32_64_]] + ; CHECK-NEXT: RET implicit $r0 + %0:gpr = LD_imm64 0 + %1:gpr = MOV_32_64 %0.sub_32 + $r0 = COPY %1:gpr + RET implicit $r0 +... + +--- +name: mov32_64_subreg_source_copy +tracksRegLiveness: true +body: | + bb.0: + liveins: $r1 + ; CHECK-LABEL: name: mov32_64_subreg_source_copy + ; CHECK: liveins: $r1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $r1 + ; CHECK-NEXT: [[MOV_32_64_:%[0-9]+]]:gpr = MOV_32_64 [[COPY]].sub_32 + ; CHECK-NEXT: $r0 = COPY [[MOV_32_64_]] + ; CHECK-NEXT: RET implicit $r0 + %0:gpr = COPY $r1 + %1:gpr = MOV_32_64 %0.sub_32 + $r0 = COPY %1:gpr + RET implicit $r0 +... diff --git a/llvm/test/CodeGen/Hexagon/autohvx/isel-build-vector-splat-word.ll b/llvm/test/CodeGen/Hexagon/autohvx/isel-build-vector-splat-word.ll new file mode 100644 index 0000000000000..bc3ffd688cdd9 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/autohvx/isel-build-vector-splat-word.ll @@ -0,0 +1,256 @@ +; RUN: llc -mtriple=hexagon < %s | FileCheck %s + +target triple = "hexagon" + +; buildHvxVectorReg packs i8 elements into i32 words before initializing +; an HVX vector from the most frequent word. That initialization must +; use a word splat even though the final vector type is i8; a byte +; splat would broadcast only the low byte of %x. +define void @splat_i32_word_into_i8_vector(ptr %out, i32 %x, i8 %y) #0 { +; CHECK-LABEL: splat_i32_word_into_i8_vector: +; CHECK: v{{[0-9]+}} = vsplat(r{{[0-9]+}}) +; CHECK-NOT: .b = vsplat +; CHECK: vmem +entry: + %x0 = trunc i32 %x to i8 + %s1 = lshr i32 %x, 8 + %x1 = trunc i32 %s1 to i8 + %s2 = lshr i32 %x, 16 + %x2 = trunc i32 %s2 to i8 + %s3 = lshr i32 %x, 24 + %x3 = trunc i32 %s3 to i8 + + %v000 = insertelement <128 x i8> poison, i8 %x0, i32 0 + %v001 = insertelement <128 x i8> %v000, i8 %x1, i32 1 + %v002 = insertelement <128 x i8> %v001, i8 %x2, i32 2 + %v003 = insertelement <128 x i8> %v002, i8 %x3, i32 3 + %v004 = insertelement <128 x i8> %v003, i8 %x0, i32 4 + %v005 = insertelement <128 x i8> %v004, i8 %x1, i32 5 + %v006 = insertelement <128 x i8> %v005, i8 %x2, i32 6 + %v007 = insertelement <128 x i8> %v006, i8 %x3, i32 7 + %v008 = insertelement <128 x i8> %v007, i8 %x0, i32 8 + %v009 = insertelement <128 x i8> %v008, i8 %x1, i32 9 + %v010 = insertelement <128 x i8> %v009, i8 %x2, i32 10 + %v011 = insertelement <128 x i8> %v010, i8 %x3, i32 11 + %v012 = insertelement <128 x i8> %v011, i8 %x0, i32 12 + %v013 = insertelement <128 x i8> %v012, i8 %x1, i32 13 + %v014 = insertelement <128 x i8> %v013, i8 %x2, i32 14 + %v015 = insertelement <128 x i8> %v014, i8 %x3, i32 15 + %v016 = insertelement <128 x i8> %v015, i8 %x0, i32 16 + %v017 = insertelement <128 x i8> %v016, i8 %x1, i32 17 + %v018 = insertelement <128 x i8> %v017, i8 %x2, i32 18 + %v019 = insertelement <128 x i8> %v018, i8 %x3, i32 19 + %v020 = insertelement <128 x i8> %v019, i8 %x0, i32 20 + %v021 = insertelement <128 x i8> %v020, i8 %x1, i32 21 + %v022 = insertelement <128 x i8> %v021, i8 %x2, i32 22 + %v023 = insertelement <128 x i8> %v022, i8 %x3, i32 23 + %v024 = insertelement <128 x i8> %v023, i8 %x0, i32 24 + %v025 = insertelement <128 x i8> %v024, i8 %x1, i32 25 + %v026 = insertelement <128 x i8> %v025, i8 %x2, i32 26 + %v027 = insertelement <128 x i8> %v026, i8 %x3, i32 27 + %v028 = insertelement <128 x i8> %v027, i8 %x0, i32 28 + %v029 = insertelement <128 x i8> %v028, i8 %x1, i32 29 + %v030 = insertelement <128 x i8> %v029, i8 %x2, i32 30 + %v031 = insertelement <128 x i8> %v030, i8 %x3, i32 31 + %v032 = insertelement <128 x i8> %v031, i8 %x0, i32 32 + %v033 = insertelement <128 x i8> %v032, i8 %x1, i32 33 + %v034 = insertelement <128 x i8> %v033, i8 %x2, i32 34 + %v035 = insertelement <128 x i8> %v034, i8 %x3, i32 35 + %v036 = insertelement <128 x i8> %v035, i8 %x0, i32 36 + %v037 = insertelement <128 x i8> %v036, i8 %x1, i32 37 + %v038 = insertelement <128 x i8> %v037, i8 %x2, i32 38 + %v039 = insertelement <128 x i8> %v038, i8 %x3, i32 39 + %v040 = insertelement <128 x i8> %v039, i8 %x0, i32 40 + %v041 = insertelement <128 x i8> %v040, i8 %x1, i32 41 + %v042 = insertelement <128 x i8> %v041, i8 %x2, i32 42 + %v043 = insertelement <128 x i8> %v042, i8 %x3, i32 43 + %v044 = insertelement <128 x i8> %v043, i8 %x0, i32 44 + %v045 = insertelement <128 x i8> %v044, i8 %x1, i32 45 + %v046 = insertelement <128 x i8> %v045, i8 %x2, i32 46 + %v047 = insertelement <128 x i8> %v046, i8 %x3, i32 47 + %v048 = insertelement <128 x i8> %v047, i8 %x0, i32 48 + %v049 = insertelement <128 x i8> %v048, i8 %x1, i32 49 + %v050 = insertelement <128 x i8> %v049, i8 %x2, i32 50 + %v051 = insertelement <128 x i8> %v050, i8 %x3, i32 51 + %v052 = insertelement <128 x i8> %v051, i8 %x0, i32 52 + %v053 = insertelement <128 x i8> %v052, i8 %x1, i32 53 + %v054 = insertelement <128 x i8> %v053, i8 %x2, i32 54 + %v055 = insertelement <128 x i8> %v054, i8 %x3, i32 55 + %v056 = insertelement <128 x i8> %v055, i8 %x0, i32 56 + %v057 = insertelement <128 x i8> %v056, i8 %x1, i32 57 + %v058 = insertelement <128 x i8> %v057, i8 %x2, i32 58 + %v059 = insertelement <128 x i8> %v058, i8 %x3, i32 59 + %v060 = insertelement <128 x i8> %v059, i8 %x0, i32 60 + %v061 = insertelement <128 x i8> %v060, i8 %x1, i32 61 + %v062 = insertelement <128 x i8> %v061, i8 %x2, i32 62 + %v063 = insertelement <128 x i8> %v062, i8 %x3, i32 63 + %v064 = insertelement <128 x i8> %v063, i8 %y, i32 64 + %v065 = insertelement <128 x i8> %v064, i8 %x1, i32 65 + %v066 = insertelement <128 x i8> %v065, i8 %x2, i32 66 + %v067 = insertelement <128 x i8> %v066, i8 %x3, i32 67 + %v068 = insertelement <128 x i8> %v067, i8 %x0, i32 68 + %v069 = insertelement <128 x i8> %v068, i8 %y, i32 69 + %v070 = insertelement <128 x i8> %v069, i8 %x2, i32 70 + %v071 = insertelement <128 x i8> %v070, i8 %x3, i32 71 + %v072 = insertelement <128 x i8> %v071, i8 %x0, i32 72 + %v073 = insertelement <128 x i8> %v072, i8 %x1, i32 73 + %v074 = insertelement <128 x i8> %v073, i8 %y, i32 74 + %v075 = insertelement <128 x i8> %v074, i8 %x3, i32 75 + %v076 = insertelement <128 x i8> %v075, i8 %x0, i32 76 + %v077 = insertelement <128 x i8> %v076, i8 %x1, i32 77 + %v078 = insertelement <128 x i8> %v077, i8 %x2, i32 78 + %v079 = insertelement <128 x i8> %v078, i8 %y, i32 79 + %v080 = insertelement <128 x i8> %v079, i8 %x0, i32 80 + %v081 = insertelement <128 x i8> %v080, i8 %x1, i32 81 + %v082 = insertelement <128 x i8> %v081, i8 %x2, i32 82 + %v083 = insertelement <128 x i8> %v082, i8 %x3, i32 83 + %v084 = insertelement <128 x i8> %v083, i8 %x0, i32 84 + %v085 = insertelement <128 x i8> %v084, i8 %x1, i32 85 + %v086 = insertelement <128 x i8> %v085, i8 %x2, i32 86 + %v087 = insertelement <128 x i8> %v086, i8 %x3, i32 87 + %v088 = insertelement <128 x i8> %v087, i8 %x0, i32 88 + %v089 = insertelement <128 x i8> %v088, i8 %x1, i32 89 + %v090 = insertelement <128 x i8> %v089, i8 %x2, i32 90 + %v091 = insertelement <128 x i8> %v090, i8 %x3, i32 91 + %v092 = insertelement <128 x i8> %v091, i8 %x0, i32 92 + %v093 = insertelement <128 x i8> %v092, i8 %x1, i32 93 + %v094 = insertelement <128 x i8> %v093, i8 %x2, i32 94 + %v095 = insertelement <128 x i8> %v094, i8 %x3, i32 95 + %v096 = insertelement <128 x i8> %v095, i8 %x0, i32 96 + %v097 = insertelement <128 x i8> %v096, i8 %x1, i32 97 + %v098 = insertelement <128 x i8> %v097, i8 %x2, i32 98 + %v099 = insertelement <128 x i8> %v098, i8 %x3, i32 99 + %v100 = insertelement <128 x i8> %v099, i8 %x0, i32 100 + %v101 = insertelement <128 x i8> %v100, i8 %x1, i32 101 + %v102 = insertelement <128 x i8> %v101, i8 %x2, i32 102 + %v103 = insertelement <128 x i8> %v102, i8 %x3, i32 103 + %v104 = insertelement <128 x i8> %v103, i8 %x0, i32 104 + %v105 = insertelement <128 x i8> %v104, i8 %x1, i32 105 + %v106 = insertelement <128 x i8> %v105, i8 %x2, i32 106 + %v107 = insertelement <128 x i8> %v106, i8 %x3, i32 107 + %v108 = insertelement <128 x i8> %v107, i8 %x0, i32 108 + %v109 = insertelement <128 x i8> %v108, i8 %x1, i32 109 + %v110 = insertelement <128 x i8> %v109, i8 %x2, i32 110 + %v111 = insertelement <128 x i8> %v110, i8 %x3, i32 111 + %v112 = insertelement <128 x i8> %v111, i8 %x0, i32 112 + %v113 = insertelement <128 x i8> %v112, i8 %x1, i32 113 + %v114 = insertelement <128 x i8> %v113, i8 %x2, i32 114 + %v115 = insertelement <128 x i8> %v114, i8 %x3, i32 115 + %v116 = insertelement <128 x i8> %v115, i8 %x0, i32 116 + %v117 = insertelement <128 x i8> %v116, i8 %x1, i32 117 + %v118 = insertelement <128 x i8> %v117, i8 %x2, i32 118 + %v119 = insertelement <128 x i8> %v118, i8 %x3, i32 119 + %v120 = insertelement <128 x i8> %v119, i8 %x0, i32 120 + %v121 = insertelement <128 x i8> %v120, i8 %x1, i32 121 + %v122 = insertelement <128 x i8> %v121, i8 %x2, i32 122 + %v123 = insertelement <128 x i8> %v122, i8 %x3, i32 123 + %v124 = insertelement <128 x i8> %v123, i8 %x0, i32 124 + %v125 = insertelement <128 x i8> %v124, i8 %x1, i32 125 + %v126 = insertelement <128 x i8> %v125, i8 %x2, i32 126 + %v127 = insertelement <128 x i8> %v126, i8 %x3, i32 127 + store <128 x i8> %v127, ptr %out, align 128 + ret void +} + +define void @splat_i8_into_i8_vector(ptr %out, i8 %x) #0 { +; CHECK-LABEL: splat_i8_into_i8_vector: +; CHECK: v{{[0-9]+}}.b = vsplat(r{{[0-9]+}}) +; CHECK: vmem +entry: + %v0 = insertelement <128 x i8> poison, i8 %x, i32 0 + %v1 = shufflevector <128 x i8> %v0, <128 x i8> poison, <128 x i32> zeroinitializer + store <128 x i8> %v1, ptr %out, align 128 + ret void +} + +; The same word-splat requirement applies when the final vector type is +; i16 and the repeated value is a packed i32 containing two halfwords. +define void @splat_i32_word_into_i16_vector(ptr %out, i32 %x, i16 %y) #0 { +; CHECK-LABEL: splat_i32_word_into_i16_vector: +; CHECK: v{{[0-9]+}} = vsplat(r{{[0-9]+}}) +; CHECK-NOT: .h = vsplat +; CHECK: vmem +entry: + %x0 = trunc i32 %x to i16 + %s1 = lshr i32 %x, 16 + %x1 = trunc i32 %s1 to i16 + %v0 = insertelement <64 x i16> poison, i16 %x0, i32 0 + %v1 = insertelement <64 x i16> %v0, i16 %x1, i32 1 + %v2 = insertelement <64 x i16> %v1, i16 %x0, i32 2 + %v3 = insertelement <64 x i16> %v2, i16 %x1, i32 3 + %v4 = insertelement <64 x i16> %v3, i16 %x0, i32 4 + %v5 = insertelement <64 x i16> %v4, i16 %x1, i32 5 + %v6 = insertelement <64 x i16> %v5, i16 %x0, i32 6 + %v7 = insertelement <64 x i16> %v6, i16 %x1, i32 7 + %v8 = insertelement <64 x i16> %v7, i16 %x0, i32 8 + %v9 = insertelement <64 x i16> %v8, i16 %x1, i32 9 + %v10 = insertelement <64 x i16> %v9, i16 %x0, i32 10 + %v11 = insertelement <64 x i16> %v10, i16 %x1, i32 11 + %v12 = insertelement <64 x i16> %v11, i16 %x0, i32 12 + %v13 = insertelement <64 x i16> %v12, i16 %x1, i32 13 + %v14 = insertelement <64 x i16> %v13, i16 %x0, i32 14 + %v15 = insertelement <64 x i16> %v14, i16 %x1, i32 15 + %v16 = insertelement <64 x i16> %v15, i16 %x0, i32 16 + %v17 = insertelement <64 x i16> %v16, i16 %x1, i32 17 + %v18 = insertelement <64 x i16> %v17, i16 %x0, i32 18 + %v19 = insertelement <64 x i16> %v18, i16 %x1, i32 19 + %v20 = insertelement <64 x i16> %v19, i16 %x0, i32 20 + %v21 = insertelement <64 x i16> %v20, i16 %x1, i32 21 + %v22 = insertelement <64 x i16> %v21, i16 %x0, i32 22 + %v23 = insertelement <64 x i16> %v22, i16 %x1, i32 23 + %v24 = insertelement <64 x i16> %v23, i16 %x0, i32 24 + %v25 = insertelement <64 x i16> %v24, i16 %x1, i32 25 + %v26 = insertelement <64 x i16> %v25, i16 %x0, i32 26 + %v27 = insertelement <64 x i16> %v26, i16 %x1, i32 27 + %v28 = insertelement <64 x i16> %v27, i16 %x0, i32 28 + %v29 = insertelement <64 x i16> %v28, i16 %x1, i32 29 + %v30 = insertelement <64 x i16> %v29, i16 %x0, i32 30 + %v31 = insertelement <64 x i16> %v30, i16 %x1, i32 31 + %v32 = insertelement <64 x i16> %v31, i16 %y, i32 32 + %v33 = insertelement <64 x i16> %v32, i16 %x1, i32 33 + %v34 = insertelement <64 x i16> %v33, i16 %x0, i32 34 + %v35 = insertelement <64 x i16> %v34, i16 %x1, i32 35 + %v36 = insertelement <64 x i16> %v35, i16 %x0, i32 36 + %v37 = insertelement <64 x i16> %v36, i16 %y, i32 37 + %v38 = insertelement <64 x i16> %v37, i16 %x0, i32 38 + %v39 = insertelement <64 x i16> %v38, i16 %x1, i32 39 + %v40 = insertelement <64 x i16> %v39, i16 %x0, i32 40 + %v41 = insertelement <64 x i16> %v40, i16 %x1, i32 41 + %v42 = insertelement <64 x i16> %v41, i16 %y, i32 42 + %v43 = insertelement <64 x i16> %v42, i16 %x1, i32 43 + %v44 = insertelement <64 x i16> %v43, i16 %x0, i32 44 + %v45 = insertelement <64 x i16> %v44, i16 %x1, i32 45 + %v46 = insertelement <64 x i16> %v45, i16 %x0, i32 46 + %v47 = insertelement <64 x i16> %v46, i16 %y, i32 47 + %v48 = insertelement <64 x i16> %v47, i16 %x0, i32 48 + %v49 = insertelement <64 x i16> %v48, i16 %x1, i32 49 + %v50 = insertelement <64 x i16> %v49, i16 %x0, i32 50 + %v51 = insertelement <64 x i16> %v50, i16 %x1, i32 51 + %v52 = insertelement <64 x i16> %v51, i16 %x0, i32 52 + %v53 = insertelement <64 x i16> %v52, i16 %x1, i32 53 + %v54 = insertelement <64 x i16> %v53, i16 %x0, i32 54 + %v55 = insertelement <64 x i16> %v54, i16 %x1, i32 55 + %v56 = insertelement <64 x i16> %v55, i16 %x0, i32 56 + %v57 = insertelement <64 x i16> %v56, i16 %x1, i32 57 + %v58 = insertelement <64 x i16> %v57, i16 %x0, i32 58 + %v59 = insertelement <64 x i16> %v58, i16 %x1, i32 59 + %v60 = insertelement <64 x i16> %v59, i16 %x0, i32 60 + %v61 = insertelement <64 x i16> %v60, i16 %x1, i32 61 + %v62 = insertelement <64 x i16> %v61, i16 %x0, i32 62 + %v63 = insertelement <64 x i16> %v62, i16 %x1, i32 63 + store <64 x i16> %v63, ptr %out, align 128 + ret void +} + +define void @splat_i16_into_i16_vector(ptr %out, i16 %x) #0 { +; CHECK-LABEL: splat_i16_into_i16_vector: +; CHECK: v{{[0-9]+}}.h = vsplat(r{{[0-9]+}}) +; CHECK: vmem +entry: + %v0 = insertelement <64 x i16> poison, i16 %x, i32 0 + %v1 = shufflevector <64 x i16> %v0, <64 x i16> poison, <64 x i32> zeroinitializer + store <64 x i16> %v1, ptr %out, align 128 + ret void +} + +attributes #0 = { nounwind "target-cpu"="hexagonv75" "target-features"="+hvxv75,+hvx-length128b" } diff --git a/llvm/test/CodeGen/RISCV/rvp-zip.ll b/llvm/test/CodeGen/RISCV/rvp-zip.ll index d639269c21eab..2f146afc23427 100644 --- a/llvm/test/CodeGen/RISCV/rvp-zip.ll +++ b/llvm/test/CodeGen/RISCV/rvp-zip.ll @@ -9,35 +9,12 @@ define <8 x i8> @test_pzip_v8i8(<4 x i8> %a, <4 x i8> %b) { ; RV32-LABEL: test_pzip_v8i8: ; RV32: # %bb.0: -; RV32-NEXT: srli a2, a1, 24 -; RV32-NEXT: srli a3, a0, 24 -; RV32-NEXT: srli a4, a1, 16 -; RV32-NEXT: srli a5, a0, 16 -; RV32-NEXT: ppaire.b a2, a3, a2 -; RV32-NEXT: ppaire.b a3, a5, a4 -; RV32-NEXT: srli a4, a1, 8 -; RV32-NEXT: srli a5, a0, 8 -; RV32-NEXT: ppaire.b a0, a0, a1 -; RV32-NEXT: ppaire.b a4, a5, a4 -; RV32-NEXT: pack a1, a3, a2 -; RV32-NEXT: pack a0, a0, a4 +; RV32-NEXT: wzip8p a0, a0, a1 ; RV32-NEXT: ret ; ; RV64-LABEL: test_pzip_v8i8: ; RV64: # %bb.0: -; RV64-NEXT: srli a2, a1, 24 -; RV64-NEXT: srli a3, a0, 24 -; RV64-NEXT: srli a4, a1, 16 -; RV64-NEXT: srli a5, a0, 16 -; RV64-NEXT: ppaire.b a2, a3, a2 -; RV64-NEXT: ppaire.b a3, a5, a4 -; RV64-NEXT: srli a4, a1, 8 -; RV64-NEXT: srli a5, a0, 8 -; RV64-NEXT: ppaire.b a0, a0, a1 -; RV64-NEXT: ppaire.b a1, a5, a4 -; RV64-NEXT: ppaire.h a2, a3, a2 -; RV64-NEXT: ppaire.h a0, a0, a1 -; RV64-NEXT: pack a0, a0, a2 +; RV64-NEXT: zip8p a0, a0, a1 ; RV64-NEXT: ret %r = shufflevector <4 x i8> %a, <4 x i8> %b, <8 x i32> ret <8 x i8> %r @@ -46,19 +23,12 @@ define <8 x i8> @test_pzip_v8i8(<4 x i8> %a, <4 x i8> %b) { define <4 x i16> @test_pzip_v4i16(<2 x i16> %a, <2 x i16> %b) { ; RV32-LABEL: test_pzip_v4i16: ; RV32: # %bb.0: -; RV32-NEXT: srli a2, a1, 16 -; RV32-NEXT: srli a3, a0, 16 -; RV32-NEXT: pack a0, a0, a1 -; RV32-NEXT: pack a1, a3, a2 +; RV32-NEXT: wzip16p a0, a0, a1 ; RV32-NEXT: ret ; ; RV64-LABEL: test_pzip_v4i16: ; RV64: # %bb.0: -; RV64-NEXT: srli a2, a1, 16 -; RV64-NEXT: srli a3, a0, 16 -; RV64-NEXT: ppaire.h a0, a0, a1 -; RV64-NEXT: ppaire.h a1, a3, a2 -; RV64-NEXT: pack a0, a0, a1 +; RV64-NEXT: zip16p a0, a0, a1 ; RV64-NEXT: ret %r = shufflevector <2 x i16> %a, <2 x i16> %b, <4 x i32> ret <4 x i16> %r diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll index 07fb8675d85e8..bce071e988f0e 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll @@ -182,27 +182,20 @@ define {<8 x i64>, <8 x i64>} @vector_deinterleave_v8i64_v16i64(<16 x i64> %vec) define {<2 x i32>, <2 x i32>, <2 x i32>} @vector_deinterleave3_v2i32_v6i32(<6 x i32> %v) nounwind { ; CHECK-LABEL: vector_deinterleave3_v2i32_v6i32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: addi a0, sp, 8 +; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 2 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 4 -; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 2 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a0, a0, 3 -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v9, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse32.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse32.v v10, (a1) ; CHECK-NEXT: vlseg3e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret %res = call {<2 x i32>, <2 x i32>, <2 x i32>} @llvm.vector.deinterleave3.v6i32(<6 x i32> %v) ret {<2 x i32>, <2 x i32>, <2 x i32>} %res @@ -211,55 +204,341 @@ define {<2 x i32>, <2 x i32>, <2 x i32>} @vector_deinterleave3_v2i32_v6i32(<6 x define {<3 x i32>, <3 x i32>, <3 x i32>} @vector_deinterleave3_v3i32_v9i32(<9 x i32> %v) nounwind { ; CHECK-LABEL: vector_deinterleave3_v3i32_v9i32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 2 -; CHECK-NEXT: sub sp, sp, a0 +; CHECK-NEXT: addi sp, sp, -48 ; CHECK-NEXT: vsetivli zero, 4, e32, m4, ta, ma ; CHECK-NEXT: vslidedown.vi v12, v8, 8 ; CHECK-NEXT: vsetivli zero, 4, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 4 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: vmv2r.v v10, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs4r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse32.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 32 +; CHECK-NEXT: vse32.v v12, (a1) ; CHECK-NEXT: vlseg3e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 2 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 48 ; CHECK-NEXT: ret %d = call {<3 x i32>, <3 x i32>, <3 x i32>} @llvm.vector.deinterleave3(<9 x i32> %v) ret {<3 x i32>, <3 x i32>, <3 x i32>} %d } +define {<15 x i32>, <15 x i32>, <15 x i32>} @vector_deinterleave3_v15i32_v45i32(<45 x i32> %v) nounwind { +; RV32-LABEL: vector_deinterleave3_v15i32_v45i32: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -640 +; RV32-NEXT: sw ra, 636(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 632(sp) # 4-byte Folded Spill +; RV32-NEXT: addi s0, sp, 640 +; RV32-NEXT: andi sp, sp, -128 +; RV32-NEXT: addi a1, sp, 252 +; RV32-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; RV32-NEXT: vse32.v v23, (a1) +; RV32-NEXT: addi a1, sp, 248 +; RV32-NEXT: vse32.v v22, (a1) +; RV32-NEXT: addi a1, sp, 244 +; RV32-NEXT: vse32.v v21, (a1) +; RV32-NEXT: addi a1, sp, 240 +; RV32-NEXT: vse32.v v20, (a1) +; RV32-NEXT: addi a1, sp, 236 +; RV32-NEXT: vse32.v v19, (a1) +; RV32-NEXT: addi a1, sp, 232 +; RV32-NEXT: vse32.v v18, (a1) +; RV32-NEXT: addi a1, sp, 228 +; RV32-NEXT: vse32.v v17, (a1) +; RV32-NEXT: addi a1, sp, 224 +; RV32-NEXT: vse32.v v16, (a1) +; RV32-NEXT: addi a1, sp, 220 +; RV32-NEXT: vse32.v v15, (a1) +; RV32-NEXT: addi a1, sp, 216 +; RV32-NEXT: vse32.v v14, (a1) +; RV32-NEXT: addi a1, sp, 212 +; RV32-NEXT: vse32.v v13, (a1) +; RV32-NEXT: addi a1, sp, 208 +; RV32-NEXT: vse32.v v12, (a1) +; RV32-NEXT: addi a1, sp, 204 +; RV32-NEXT: vse32.v v11, (a1) +; RV32-NEXT: addi a1, sp, 200 +; RV32-NEXT: vse32.v v10, (a1) +; RV32-NEXT: addi a1, sp, 196 +; RV32-NEXT: vse32.v v9, (a1) +; RV32-NEXT: addi a1, sp, 192 +; RV32-NEXT: vse32.v v8, (a1) +; RV32-NEXT: addi a2, a0, 64 +; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV32-NEXT: vle32.v v8, (a2) +; RV32-NEXT: addi a2, sp, 384 +; RV32-NEXT: vse32.v v8, (a2) +; RV32-NEXT: addi a3, a0, 96 +; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; RV32-NEXT: vle32.v v8, (a3) +; RV32-NEXT: addi a3, sp, 416 +; RV32-NEXT: vse32.v v8, (a3) +; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV32-NEXT: vle32.v v8, (a0) +; RV32-NEXT: addi a3, sp, 64 +; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV32-NEXT: vse32.v v8, (a3) +; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV32-NEXT: vle32.v v12, (a1) +; RV32-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; RV32-NEXT: vslidedown.vi v16, v12, 8 +; RV32-NEXT: mv a1, sp +; RV32-NEXT: vslidedown.vi v8, v8, 8 +; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV32-NEXT: vse32.v v12, (a1) +; RV32-NEXT: addi a3, sp, 32 +; RV32-NEXT: vse32.v v16, (a3) +; RV32-NEXT: addi a3, sp, 96 +; RV32-NEXT: vse32.v v8, (a3) +; RV32-NEXT: lw a0, 112(a0) +; RV32-NEXT: sw a0, 432(sp) +; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV32-NEXT: vle32.v v8, (a2) +; RV32-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; RV32-NEXT: vslidedown.vi v12, v8, 8 +; RV32-NEXT: addi a0, sp, 128 +; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV32-NEXT: vse32.v v8, (a0) +; RV32-NEXT: addi a0, sp, 160 +; RV32-NEXT: vse32.v v12, (a0) +; RV32-NEXT: vlseg3e32.v v20, (a3) +; RV32-NEXT: vlseg3e32.v v12, (a1) +; RV32-NEXT: vmv4r.v v28, v20 +; RV32-NEXT: vmv2r.v v30, v8 +; RV32-NEXT: vmv4r.v v8, v12 +; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV32-NEXT: vslideup.vi v8, v28, 8 +; RV32-NEXT: vmv2r.v v12, v14 +; RV32-NEXT: vmv2r.v v20, v22 +; RV32-NEXT: vslideup.vi v12, v20, 8 +; RV32-NEXT: vslideup.vi v16, v24, 8 +; RV32-NEXT: addi sp, s0, -640 +; RV32-NEXT: lw ra, 636(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 632(sp) # 4-byte Folded Reload +; RV32-NEXT: addi sp, sp, 640 +; RV32-NEXT: ret +; +; RV64-LABEL: vector_deinterleave3_v15i32_v45i32: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -640 +; RV64-NEXT: sd ra, 632(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 624(sp) # 8-byte Folded Spill +; RV64-NEXT: addi s0, sp, 640 +; RV64-NEXT: andi sp, sp, -128 +; RV64-NEXT: addi a1, a0, 112 +; RV64-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; RV64-NEXT: vle32.v v24, (a1) +; RV64-NEXT: addi a1, sp, 252 +; RV64-NEXT: vse32.v v23, (a1) +; RV64-NEXT: addi a1, sp, 248 +; RV64-NEXT: vse32.v v22, (a1) +; RV64-NEXT: addi a1, sp, 244 +; RV64-NEXT: vse32.v v21, (a1) +; RV64-NEXT: addi a1, sp, 240 +; RV64-NEXT: vse32.v v20, (a1) +; RV64-NEXT: addi a1, sp, 236 +; RV64-NEXT: vse32.v v19, (a1) +; RV64-NEXT: addi a1, sp, 232 +; RV64-NEXT: vse32.v v18, (a1) +; RV64-NEXT: addi a1, sp, 228 +; RV64-NEXT: vse32.v v17, (a1) +; RV64-NEXT: addi a1, sp, 224 +; RV64-NEXT: vse32.v v16, (a1) +; RV64-NEXT: addi a1, sp, 220 +; RV64-NEXT: vse32.v v15, (a1) +; RV64-NEXT: addi a1, sp, 216 +; RV64-NEXT: vse32.v v14, (a1) +; RV64-NEXT: addi a1, sp, 212 +; RV64-NEXT: vse32.v v13, (a1) +; RV64-NEXT: addi a1, sp, 208 +; RV64-NEXT: vse32.v v12, (a1) +; RV64-NEXT: addi a1, sp, 204 +; RV64-NEXT: vse32.v v11, (a1) +; RV64-NEXT: addi a1, sp, 200 +; RV64-NEXT: vse32.v v10, (a1) +; RV64-NEXT: addi a1, sp, 196 +; RV64-NEXT: vse32.v v9, (a1) +; RV64-NEXT: addi a1, sp, 192 +; RV64-NEXT: vse32.v v8, (a1) +; RV64-NEXT: addi a2, a0, 64 +; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV64-NEXT: vle32.v v8, (a2) +; RV64-NEXT: addi a2, sp, 384 +; RV64-NEXT: vse32.v v8, (a2) +; RV64-NEXT: addi a3, a0, 96 +; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; RV64-NEXT: vle32.v v8, (a3) +; RV64-NEXT: addi a3, sp, 416 +; RV64-NEXT: vse32.v v8, (a3) +; RV64-NEXT: addi a3, sp, 432 +; RV64-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; RV64-NEXT: vse32.v v24, (a3) +; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV64-NEXT: vle32.v v8, (a0) +; RV64-NEXT: addi a0, sp, 64 +; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV64-NEXT: vse32.v v8, (a0) +; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV64-NEXT: vle32.v v12, (a1) +; RV64-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; RV64-NEXT: vslidedown.vi v16, v12, 8 +; RV64-NEXT: mv a0, sp +; RV64-NEXT: vslidedown.vi v8, v8, 8 +; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV64-NEXT: vse32.v v12, (a0) +; RV64-NEXT: addi a1, sp, 32 +; RV64-NEXT: vse32.v v16, (a1) +; RV64-NEXT: addi a1, sp, 96 +; RV64-NEXT: vse32.v v8, (a1) +; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV64-NEXT: vle32.v v8, (a2) +; RV64-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; RV64-NEXT: vslidedown.vi v12, v8, 8 +; RV64-NEXT: addi a2, sp, 128 +; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV64-NEXT: vse32.v v8, (a2) +; RV64-NEXT: addi a2, sp, 160 +; RV64-NEXT: vse32.v v12, (a2) +; RV64-NEXT: vlseg3e32.v v20, (a1) +; RV64-NEXT: vlseg3e32.v v12, (a0) +; RV64-NEXT: vmv4r.v v28, v20 +; RV64-NEXT: vmv2r.v v30, v8 +; RV64-NEXT: vmv4r.v v8, v12 +; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV64-NEXT: vslideup.vi v8, v28, 8 +; RV64-NEXT: vmv2r.v v12, v14 +; RV64-NEXT: vmv2r.v v20, v22 +; RV64-NEXT: vslideup.vi v12, v20, 8 +; RV64-NEXT: vslideup.vi v16, v24, 8 +; RV64-NEXT: addi sp, s0, -640 +; RV64-NEXT: ld ra, 632(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 624(sp) # 8-byte Folded Reload +; RV64-NEXT: addi sp, sp, 640 +; RV64-NEXT: ret +; +; ZVZIP-LABEL: vector_deinterleave3_v15i32_v45i32: +; ZVZIP: # %bb.0: +; ZVZIP-NEXT: addi sp, sp, -640 +; ZVZIP-NEXT: sd ra, 632(sp) # 8-byte Folded Spill +; ZVZIP-NEXT: sd s0, 624(sp) # 8-byte Folded Spill +; ZVZIP-NEXT: addi s0, sp, 640 +; ZVZIP-NEXT: andi sp, sp, -128 +; ZVZIP-NEXT: addi a1, a0, 112 +; ZVZIP-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; ZVZIP-NEXT: vle32.v v24, (a1) +; ZVZIP-NEXT: addi a1, sp, 252 +; ZVZIP-NEXT: vse32.v v23, (a1) +; ZVZIP-NEXT: addi a1, sp, 248 +; ZVZIP-NEXT: vse32.v v22, (a1) +; ZVZIP-NEXT: addi a1, sp, 244 +; ZVZIP-NEXT: vse32.v v21, (a1) +; ZVZIP-NEXT: addi a1, sp, 240 +; ZVZIP-NEXT: vse32.v v20, (a1) +; ZVZIP-NEXT: addi a1, sp, 236 +; ZVZIP-NEXT: vse32.v v19, (a1) +; ZVZIP-NEXT: addi a1, sp, 232 +; ZVZIP-NEXT: vse32.v v18, (a1) +; ZVZIP-NEXT: addi a1, sp, 228 +; ZVZIP-NEXT: vse32.v v17, (a1) +; ZVZIP-NEXT: addi a1, sp, 224 +; ZVZIP-NEXT: vse32.v v16, (a1) +; ZVZIP-NEXT: addi a1, sp, 220 +; ZVZIP-NEXT: vse32.v v15, (a1) +; ZVZIP-NEXT: addi a1, sp, 216 +; ZVZIP-NEXT: vse32.v v14, (a1) +; ZVZIP-NEXT: addi a1, sp, 212 +; ZVZIP-NEXT: vse32.v v13, (a1) +; ZVZIP-NEXT: addi a1, sp, 208 +; ZVZIP-NEXT: vse32.v v12, (a1) +; ZVZIP-NEXT: addi a1, sp, 204 +; ZVZIP-NEXT: vse32.v v11, (a1) +; ZVZIP-NEXT: addi a1, sp, 200 +; ZVZIP-NEXT: vse32.v v10, (a1) +; ZVZIP-NEXT: addi a1, sp, 196 +; ZVZIP-NEXT: vse32.v v9, (a1) +; ZVZIP-NEXT: addi a1, sp, 192 +; ZVZIP-NEXT: vse32.v v8, (a1) +; ZVZIP-NEXT: addi a2, a0, 64 +; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; ZVZIP-NEXT: vle32.v v8, (a2) +; ZVZIP-NEXT: addi a2, sp, 384 +; ZVZIP-NEXT: vse32.v v8, (a2) +; ZVZIP-NEXT: addi a3, a0, 96 +; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; ZVZIP-NEXT: vle32.v v8, (a3) +; ZVZIP-NEXT: addi a3, sp, 416 +; ZVZIP-NEXT: vse32.v v8, (a3) +; ZVZIP-NEXT: addi a3, sp, 432 +; ZVZIP-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; ZVZIP-NEXT: vse32.v v24, (a3) +; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; ZVZIP-NEXT: vle32.v v8, (a0) +; ZVZIP-NEXT: addi a0, sp, 64 +; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; ZVZIP-NEXT: vse32.v v8, (a0) +; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; ZVZIP-NEXT: vle32.v v12, (a1) +; ZVZIP-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; ZVZIP-NEXT: vslidedown.vi v16, v12, 8 +; ZVZIP-NEXT: mv a0, sp +; ZVZIP-NEXT: vslidedown.vi v8, v8, 8 +; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; ZVZIP-NEXT: vse32.v v12, (a0) +; ZVZIP-NEXT: addi a1, sp, 32 +; ZVZIP-NEXT: vse32.v v16, (a1) +; ZVZIP-NEXT: addi a1, sp, 96 +; ZVZIP-NEXT: vse32.v v8, (a1) +; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; ZVZIP-NEXT: vle32.v v8, (a2) +; ZVZIP-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; ZVZIP-NEXT: vslidedown.vi v12, v8, 8 +; ZVZIP-NEXT: addi a2, sp, 128 +; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; ZVZIP-NEXT: vse32.v v8, (a2) +; ZVZIP-NEXT: addi a2, sp, 160 +; ZVZIP-NEXT: vse32.v v12, (a2) +; ZVZIP-NEXT: vlseg3e32.v v20, (a1) +; ZVZIP-NEXT: vlseg3e32.v v12, (a0) +; ZVZIP-NEXT: vmv4r.v v28, v20 +; ZVZIP-NEXT: vmv2r.v v30, v8 +; ZVZIP-NEXT: vmv4r.v v8, v12 +; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; ZVZIP-NEXT: vslideup.vi v8, v28, 8 +; ZVZIP-NEXT: vmv2r.v v12, v14 +; ZVZIP-NEXT: vmv2r.v v20, v22 +; ZVZIP-NEXT: vslideup.vi v12, v20, 8 +; ZVZIP-NEXT: vslideup.vi v16, v24, 8 +; ZVZIP-NEXT: addi sp, s0, -640 +; ZVZIP-NEXT: ld ra, 632(sp) # 8-byte Folded Reload +; ZVZIP-NEXT: ld s0, 624(sp) # 8-byte Folded Reload +; ZVZIP-NEXT: addi sp, sp, 640 +; ZVZIP-NEXT: ret + %d = call {<15 x i32>, <15 x i32>, <15 x i32>} @llvm.vector.deinterleave3(<45 x i32> %v) + ret {<15 x i32>, <15 x i32>, <15 x i32>} %d +} + define {<2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>} @vector_deinterleave4_v2i32_v8i32(<8 x i32> %v) nounwind { ; CHECK-LABEL: vector_deinterleave4_v2i32_v8i32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 +; CHECK-NEXT: addi sp, sp, -32 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 6 ; CHECK-NEXT: vslidedown.vi v12, v8, 4 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse32.v v10, (a1) ; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 2 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a0, a0, 3 -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vx v12, v10, a0 -; CHECK-NEXT: vslideup.vx v8, v9, a0 -; CHECK-NEXT: vmv.v.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse32.v v8, (a1) ; CHECK-NEXT: vlseg4e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret %res = call {<2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>} @llvm.vector.deinterleave4.v8i32(<8 x i32> %v) ret {<2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>} %res @@ -268,33 +547,30 @@ define {<2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>} @vector_deinterleave4_v2i32_ define {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @vector_deinterleave5_v2i16_v10i16(<10 x i16> %v) nounwind { ; CHECK-LABEL: vector_deinterleave5_v2i16_v10i16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a0, sp, 12 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v12, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg5e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret %res = call {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @llvm.vector.deinterleave5.v10i16(<10 x i16> %v) ret {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} %res @@ -303,35 +579,34 @@ define {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @vector_deinterle define {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @vector_deinterleave6_v2i16_v12i16(<12 x i16> %v) nounwind { ; CHECK-LABEL: vector_deinterleave6_v2i16_v12i16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 10 ; CHECK-NEXT: vslidedown.vi v12, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 -; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v13, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v13, a1 -; CHECK-NEXT: vslideup.vx v12, v10, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg6e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret %res = call {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @llvm.vector.deinterleave6.v12i16(<12 x i16> %v) ret {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} %res @@ -341,37 +616,35 @@ define {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>} @v ; CHECK-LABEL: vector_deinterleave7_v14i8_v2i8: ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: csrr a0, vlenb +; CHECK-NEXT: addi a0, sp, 2 ; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 10 -; CHECK-NEXT: vslidedown.vi v10, v8, 8 -; CHECK-NEXT: vslidedown.vi v11, v8, 12 -; CHECK-NEXT: vslidedown.vi v12, v8, 2 -; CHECK-NEXT: vslidedown.vi v13, v8, 4 -; CHECK-NEXT: vmv1r.v v14, v8 -; CHECK-NEXT: vslidedown.vi v8, v8, 6 -; CHECK-NEXT: srli a1, a0, 2 -; CHECK-NEXT: srli a2, a0, 3 -; CHECK-NEXT: vsetvli zero, a1, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vx v14, v12, a2 -; CHECK-NEXT: add a3, a1, a2 -; CHECK-NEXT: vslideup.vx v10, v9, a2 -; CHECK-NEXT: vsetvli zero, a3, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vx v14, v13, a1 -; CHECK-NEXT: vslideup.vx v10, v11, a1 -; CHECK-NEXT: vsetvli a1, zero, e8, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v14, v8, a3 -; CHECK-NEXT: srli a0, a0, 1 -; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma -; CHECK-NEXT: vslideup.vx v14, v10, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs1r.v v14, (a0) -; CHECK-NEXT: vsetvli a1, zero, e8, mf8, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 12 +; CHECK-NEXT: vslidedown.vi v10, v8, 10 +; CHECK-NEXT: vslidedown.vi v11, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vse8.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse8.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vse8.v v8, (a1) ; CHECK-NEXT: vlseg7e8.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: add sp, sp, a0 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %res = call {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>} @llvm.vector.deinterleave7.v14i8(<14 x i8> %v) @@ -382,38 +655,40 @@ define {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 ; CHECK-LABEL: vector_deinterleave8_v16i8_v2i8: ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: csrr a0, vlenb ; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 10 -; CHECK-NEXT: vslidedown.vi v10, v8, 8 -; CHECK-NEXT: vslidedown.vi v11, v8, 12 -; CHECK-NEXT: vslidedown.vi v12, v8, 14 -; CHECK-NEXT: vslidedown.vi v13, v8, 2 -; CHECK-NEXT: vslidedown.vi v14, v8, 4 -; CHECK-NEXT: vslidedown.vi v15, v8, 6 -; CHECK-NEXT: srli a1, a0, 2 -; CHECK-NEXT: srli a2, a0, 3 -; CHECK-NEXT: vsetvli zero, a1, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vx v10, v9, a2 -; CHECK-NEXT: vslideup.vx v8, v13, a2 -; CHECK-NEXT: add a2, a1, a2 -; CHECK-NEXT: vsetvli zero, a2, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vx v10, v11, a1 -; CHECK-NEXT: vslideup.vx v8, v14, a1 -; CHECK-NEXT: vsetvli a1, zero, e8, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v10, v12, a2 -; CHECK-NEXT: vslideup.vx v8, v15, a2 -; CHECK-NEXT: srli a0, a0, 1 -; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v10, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs1r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e8, mf8, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 14 +; CHECK-NEXT: vslidedown.vi v10, v8, 12 +; CHECK-NEXT: vslidedown.vi v11, v8, 10 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v9, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse8.v v10, (a1) +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vse8.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 2 +; CHECK-NEXT: vse8.v v8, (a1) ; CHECK-NEXT: vlseg8e8.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: add sp, sp, a0 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %res = call {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>} @llvm.vector.deinterleave8.v16i8(<16 x i8> %v) @@ -595,30 +870,21 @@ ret {<4 x double>, <4 x double>} %retval define {<2 x float>, <2 x float>, <2 x float>} @vector_deinterleave3_v6f32_v2f32(<6 x float> %v) { ; CHECK-LABEL: vector_deinterleave3_v6f32_v2f32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: addi a0, sp, 8 +; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 2 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 4 -; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 2 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a0, a0, 3 -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v9, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse32.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse32.v v10, (a1) ; CHECK-NEXT: vlseg3e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x float>, <2 x float>, <2 x float>} @llvm.vector.deinterleave3.v6f32(<6 x float> %v) @@ -628,32 +894,25 @@ define {<2 x float>, <2 x float>, <2 x float>} @vector_deinterleave3_v6f32_v2f32 define {<2 x float>, <2 x float>, <2 x float>, <2 x float>} @vector_deinterleave4_v8f32_v2f32(<8 x float> %v) { ; CHECK-LABEL: vector_deinterleave4_v8f32_v2f32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 6 ; CHECK-NEXT: vslidedown.vi v12, v8, 4 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse32.v v10, (a1) ; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 2 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a0, a0, 3 -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vx v12, v10, a0 -; CHECK-NEXT: vslideup.vx v8, v9, a0 -; CHECK-NEXT: vmv.v.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse32.v v8, (a1) ; CHECK-NEXT: vlseg4e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x float>, <2 x float>, <2 x float>, <2 x float>} @llvm.vector.deinterleave4.v8f32(<8 x float> %v) @@ -663,36 +922,31 @@ define {<2 x float>, <2 x float>, <2 x float>, <2 x float>} @vector_deinterleave define {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @vector_deinterleave5_v10f16_v2f16(<10 x half> %v) { ; CHECK-LABEL: vector_deinterleave5_v10f16_v2f16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a0, sp, 12 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v12, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg5e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @llvm.vector.deinterleave5.v10f16(<10 x half> %v) @@ -702,36 +956,31 @@ define {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @vector_dein define {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @vector_deinterleave5_v10bf16_v2bf16(<10 x bfloat> %v) { ; CHECK-LABEL: vector_deinterleave5_v10bf16_v2bf16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a0, sp, 12 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v12, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg5e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @llvm.vector.deinterleave5.v10bf16(<10 x bfloat> %v) @@ -741,38 +990,35 @@ define {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @v define {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @vector_deinterleave6_v12f16_v2f16(<12 x half> %v) { ; CHECK-LABEL: vector_deinterleave6_v12f16_v2f16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 10 ; CHECK-NEXT: vslidedown.vi v12, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 -; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v13, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v13, a1 -; CHECK-NEXT: vslideup.vx v12, v10, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg6e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @llvm.vector.deinterleave6.v12f16(<12 x half> %v) @@ -782,38 +1028,35 @@ define {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} define {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @vector_deinterleave6_v12bf16_v2bf16(<12 x bfloat> %v) { ; CHECK-LABEL: vector_deinterleave6_v12bf16_v2bf16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 10 ; CHECK-NEXT: vslidedown.vi v12, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 -; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v13, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v13, a1 -; CHECK-NEXT: vslideup.vx v12, v10, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg6e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @llvm.vector.deinterleave6.v12bf16(<12 x bfloat> %v) @@ -825,38 +1068,35 @@ define {<1 x half>, <1 x half>, <1 x half>, <1 x half>, <1 x half>, <1 x half>, ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi a0, sp, 2 ; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 3 -; CHECK-NEXT: vslidedown.vi v11, v8, 2 -; CHECK-NEXT: vmv1r.v v10, v8 -; CHECK-NEXT: vslidedown.vi v12, v8, 1 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v10, v12, a1 -; CHECK-NEXT: vsetvli a2, zero, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 5 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vslideup.vx v10, v11, a0 +; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: vslidedown.vi v10, v8, 5 ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v8, v8, 6 -; CHECK-NEXT: vslideup.vx v11, v8, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v10, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 3 +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 2 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg7e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret @@ -869,38 +1109,35 @@ define {<1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi a0, sp, 2 ; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 3 -; CHECK-NEXT: vslidedown.vi v11, v8, 2 -; CHECK-NEXT: vmv1r.v v10, v8 -; CHECK-NEXT: vslidedown.vi v12, v8, 1 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v10, v12, a1 -; CHECK-NEXT: vsetvli a2, zero, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 5 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vslideup.vx v10, v11, a0 +; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: vslidedown.vi v10, v8, 5 ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v8, v8, 6 -; CHECK-NEXT: vslideup.vx v11, v8, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v10, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 3 +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 2 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg7e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret @@ -913,39 +1150,40 @@ define {<1 x half>, <1 x half>, <1 x half>, <1 x half>, <1 x half>, <1 x half>, ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 ; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v10, v8, 7 -; CHECK-NEXT: vslidedown.vi v11, v8, 6 -; CHECK-NEXT: vslidedown.vi v12, v8, 5 -; CHECK-NEXT: vslidedown.vi v9, v8, 4 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v10, a1 -; CHECK-NEXT: vslideup.vx v9, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v9, v11, a0 -; CHECK-NEXT: vslidedown.vi v10, v8, 3 -; CHECK-NEXT: vslidedown.vi v11, v8, 2 -; CHECK-NEXT: vslidedown.vi v12, v8, 1 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v10, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 7 +; CHECK-NEXT: vslidedown.vi v10, v8, 6 +; CHECK-NEXT: vslidedown.vi v11, v8, 5 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 4 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 3 +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 2 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 2 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg8e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret @@ -958,45 +1196,43 @@ define {<1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 ; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v10, v8, 7 -; CHECK-NEXT: vslidedown.vi v11, v8, 6 -; CHECK-NEXT: vslidedown.vi v12, v8, 5 -; CHECK-NEXT: vslidedown.vi v9, v8, 4 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v10, a1 -; CHECK-NEXT: vslideup.vx v9, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v9, v11, a0 -; CHECK-NEXT: vslidedown.vi v10, v8, 3 -; CHECK-NEXT: vslidedown.vi v11, v8, 2 -; CHECK-NEXT: vslidedown.vi v12, v8, 1 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v10, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 7 +; CHECK-NEXT: vslidedown.vi v10, v8, 6 +; CHECK-NEXT: vslidedown.vi v11, v8, 5 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 4 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 3 +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 2 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 2 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg8e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>} @llvm.vector.deinterleave8.v8bf16(<8 x bfloat> %v) ret {<1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>} %res } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; RV32: {{.*}} -; RV64: {{.*}} diff --git a/llvm/test/CodeGen/RISCV/zero-call-used-regs.ll b/llvm/test/CodeGen/RISCV/zero-call-used-regs.ll index 28e6c792b9dfd..46b0cba76194b 100644 --- a/llvm/test/CodeGen/RISCV/zero-call-used-regs.ll +++ b/llvm/test/CodeGen/RISCV/zero-call-used-regs.ll @@ -281,4 +281,59 @@ entry: ret double %mul } +define double @used_zdinx(double noundef %a, double noundef %b, float noundef %c) #1 "zero-call-used-regs"="used" { +; 64-BITS-LABEL: used_zdinx: +; 64-BITS: # %bb.0: # %entry +; 64-BITS-NEXT: fmul.d a0, a0, a1 +; 64-BITS-NEXT: fcvt.d.s a1, a2 +; 64-BITS-NEXT: fmul.d a0, a0, a1 +; 64-BITS-NEXT: li a1, 0 +; 64-BITS-NEXT: li a2, 0 +; 64-BITS-NEXT: ret +; +; 32-BITS-LABEL: used_zdinx: +; 32-BITS: # %bb.0: # %entry +; 32-BITS-NEXT: fmul.d a0, a0, a2 +; 32-BITS-NEXT: fcvt.d.s a2, a4 +; 32-BITS-NEXT: fmul.d a0, a0, a2 +; 32-BITS-NEXT: li a2, 0 +; 32-BITS-NEXT: li a3, 0 +; 32-BITS-NEXT: li a4, 0 +; 32-BITS-NEXT: ret + +entry: + %conv = fpext float %c to double + %mul1 = fmul double %a, %b + %mul2 = fmul double %mul1, %conv + ret double %mul2 +} + +define double @used_arg_zdinx(double noundef %a, double noundef %b, float noundef %c) #1 "zero-call-used-regs"="used-arg" { +; 64-BITS-LABEL: used_arg_zdinx: +; 64-BITS: # %bb.0: # %entry +; 64-BITS-NEXT: fmul.d a0, a0, a1 +; 64-BITS-NEXT: fcvt.d.s a1, a2 +; 64-BITS-NEXT: fmul.d a0, a0, a1 +; 64-BITS-NEXT: li a1, 0 +; 64-BITS-NEXT: li a2, 0 +; 64-BITS-NEXT: ret +; +; 32-BITS-LABEL: used_arg_zdinx: +; 32-BITS: # %bb.0: # %entry +; 32-BITS-NEXT: fmul.d a0, a0, a2 +; 32-BITS-NEXT: fcvt.d.s a2, a4 +; 32-BITS-NEXT: fmul.d a0, a0, a2 +; 32-BITS-NEXT: li a2, 0 +; 32-BITS-NEXT: li a3, 0 +; 32-BITS-NEXT: li a4, 0 +; 32-BITS-NEXT: ret + +entry: + %conv = fpext float %c to double + %mul1 = fmul double %a, %b + %mul2 = fmul double %mul1, %conv + ret double %mul2 +} + attributes #0 = { "target-cpu"="generic" "target-features"="+m,+f,+d" } +attributes #1 = { "target-cpu"="generic" "target-features"="+m,+zdinx" } diff --git a/llvm/test/CodeGen/SystemZ/zos-align.ll b/llvm/test/CodeGen/SystemZ/zos-align.ll new file mode 100644 index 0000000000000..59827dec16079 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/zos-align.ll @@ -0,0 +1,28 @@ +; Test alignment of global constants +; +; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z10 | FileCheck %s + +@data = global [8 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7], align 4096 + +; CHECK: * @data +; CHECK-NEXT: data CSECT +; CHECK-NEXT: C_WSA64 CATTR ALIGN(12),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(dat +; CHECK-NEXT: ta) +; CHECK-NEXT: data XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(EXPORT) +; CHECK-NEXT: DS 0B +; CHECK-NEXT: * 0x0 +; CHECK-NEXT: DC XL4'00000000' +; CHECK-NEXT: * 0x1 +; CHECK-NEXT: DC XL4'00000001' +; CHECK-NEXT: * 0x2 +; CHECK-NEXT: DC XL4'00000002' +; CHECK-NEXT: * 0x3 +; CHECK-NEXT: DC XL4'00000003' +; CHECK-NEXT: * 0x4 +; CHECK-NEXT: DC XL4'00000004' +; CHECK-NEXT: * 0x5 +; CHECK-NEXT: DC XL4'00000005' +; CHECK-NEXT: * 0x6 +; CHECK-NEXT: DC XL4'00000006' +; CHECK-NEXT: * 0x7 +; CHECK-NEXT: DC XL4'00000007' diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll index c5020fcb9f24a..f4b9667d5d915 100644 --- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll +++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll @@ -46,7 +46,7 @@ entry: ; CHECK-NEXT: 0000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00 ; CHECK-NEXT: 0000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00 ; CHECK-NEXT: 0000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 08 -; CHECK-NEXT: 0000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4 +; CHECK-NEXT: 0000e0 00 00 04 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4 ; ESD record, type ED. ; The name is C_@@QPPA2. diff --git a/llvm/test/CodeGen/X86/combine-pmaddwd.ll b/llvm/test/CodeGen/X86/combine-pmaddwd.ll index d1e5e720af7fb..4fe3569df88e9 100644 --- a/llvm/test/CodeGen/X86/combine-pmaddwd.ll +++ b/llvm/test/CodeGen/X86/combine-pmaddwd.ll @@ -1,8 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE2 -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=CHECK,SSE,SSE41 -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=CHECK,AVX,AVX1 -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=CHECK,AVX,AVX2 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s --check-prefixes=CHECK,SSE,SSE2 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE42 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=sandybridge | FileCheck %s --check-prefixes=CHECK,AVX,AVX1 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK,AVX,AVX2 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=CHECK,AVX,AVX512 define <4 x i32> @combine_pmaddwd_zero(<8 x i16> %a0, <8 x i16> %a1) { ; SSE-LABEL: combine_pmaddwd_zero: @@ -53,6 +54,13 @@ define <8 x i32> @combine_pmaddwd_concat(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> ; AVX2-NEXT: vpmaddwd %xmm3, %xmm2, %xmm1 ; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_pmaddwd_concat: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmaddwd %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: vpmaddwd %xmm3, %xmm2, %xmm1 +; AVX512-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 +; AVX512-NEXT: retq %1 = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a0, <8 x i16> %a1) %2 = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a2, <8 x i16> %a3) %3 = shufflevector <4 x i32> %1, <4 x i32> %2, <8 x i32> @@ -60,19 +68,12 @@ define <8 x i32> @combine_pmaddwd_concat(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> } define <8 x i32> @combine_pmaddwd_concat_freeze(<8 x i16> %a0, <8 x i16> %a1) { -; SSE2-LABEL: combine_pmaddwd_concat_freeze: -; SSE2: # %bb.0: -; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] -; SSE2-NEXT: pmaddwd %xmm2, %xmm0 -; SSE2-NEXT: pmaddwd %xmm2, %xmm1 -; SSE2-NEXT: retq -; -; SSE41-LABEL: combine_pmaddwd_concat_freeze: -; SSE41: # %bb.0: -; SSE41-NEXT: pmovsxbw {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] -; SSE41-NEXT: pmaddwd %xmm2, %xmm0 -; SSE41-NEXT: pmaddwd %xmm2, %xmm1 -; SSE41-NEXT: retq +; SSE-LABEL: combine_pmaddwd_concat_freeze: +; SSE: # %bb.0: +; SSE-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] +; SSE-NEXT: pmaddwd %xmm2, %xmm0 +; SSE-NEXT: pmaddwd %xmm2, %xmm1 +; SSE-NEXT: retq ; ; AVX1-LABEL: combine_pmaddwd_concat_freeze: ; AVX1: # %bb.0: @@ -88,6 +89,13 @@ define <8 x i32> @combine_pmaddwd_concat_freeze(<8 x i16> %a0, <8 x i16> %a1) { ; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 ; AVX2-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_pmaddwd_concat_freeze: +; AVX512: # %bb.0: +; AVX512-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0 +; AVX512-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 +; AVX512-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +; AVX512-NEXT: retq %lo = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a0, <8 x i16> ) %hi = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a1, <8 x i16> ) %flo = freeze <4 x i32> %lo @@ -113,11 +121,11 @@ define <8 x i32> @combine_pmaddwd_concat_add(ptr %px0, ptr %py0) { ; SSE2-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7] ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] ; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; SSE2-NEXT: pshuflw {{.*#+}} xmm2 = mem[0,2,2,3,4,5,6,7] ; SSE2-NEXT: pmaddwd %xmm1, %xmm0 -; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = mem[0,2,2,3,4,5,6,7] -; SSE2-NEXT: pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,7] -; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] +; SSE2-NEXT: pshufhw {{.*#+}} xmm1 = xmm2[0,1,2,3,4,6,6,7] ; SSE2-NEXT: pshuflw {{.*#+}} xmm2 = mem[0,2,2,3,4,5,6,7] +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] ; SSE2-NEXT: pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,4,6,6,7] ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3] ; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3] @@ -131,32 +139,32 @@ define <8 x i32> @combine_pmaddwd_concat_add(ptr %px0, ptr %py0) { ; SSE2-NEXT: pmaddwd %xmm2, %xmm1 ; SSE2-NEXT: retq ; -; SSE41-LABEL: combine_pmaddwd_concat_add: -; SSE41: # %bb.0: -; SSE41-NEXT: movdqa (%rdi), %xmm0 -; SSE41-NEXT: movdqa 16(%rdi), %xmm1 -; SSE41-NEXT: movdqa 32(%rdi), %xmm2 -; SSE41-NEXT: movdqa 48(%rdi), %xmm3 -; SSE41-NEXT: movdqa (%rsi), %xmm4 -; SSE41-NEXT: movdqa 16(%rsi), %xmm5 -; SSE41-NEXT: movdqa 32(%rsi), %xmm6 -; SSE41-NEXT: movdqa 48(%rsi), %xmm7 -; SSE41-NEXT: movq {{.*#+}} xmm8 = [0,1,4,5,8,9,12,13,0,0,0,0,0,0,0,0] -; SSE41-NEXT: pshufb %xmm8, %xmm6 -; SSE41-NEXT: pshufb %xmm8, %xmm4 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm6[0],xmm4[1],xmm6[1],xmm4[2],xmm6[2],xmm4[3],xmm6[3] -; SSE41-NEXT: pshufb %xmm8, %xmm2 -; SSE41-NEXT: pshufb %xmm8, %xmm0 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] -; SSE41-NEXT: pmaddwd %xmm4, %xmm0 -; SSE41-NEXT: pshufb %xmm8, %xmm7 -; SSE41-NEXT: pshufb %xmm8, %xmm5 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm7[0],xmm5[1],xmm7[1],xmm5[2],xmm7[2],xmm5[3],xmm7[3] -; SSE41-NEXT: pshufb %xmm8, %xmm3 -; SSE41-NEXT: pshufb %xmm8, %xmm1 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3] -; SSE41-NEXT: pmaddwd %xmm5, %xmm1 -; SSE41-NEXT: retq +; SSE42-LABEL: combine_pmaddwd_concat_add: +; SSE42: # %bb.0: +; SSE42-NEXT: movdqa (%rdi), %xmm0 +; SSE42-NEXT: movdqa 16(%rdi), %xmm1 +; SSE42-NEXT: movdqa 32(%rdi), %xmm2 +; SSE42-NEXT: movdqa 48(%rdi), %xmm3 +; SSE42-NEXT: movdqa (%rsi), %xmm4 +; SSE42-NEXT: movdqa 16(%rsi), %xmm5 +; SSE42-NEXT: movdqa 32(%rsi), %xmm6 +; SSE42-NEXT: movdqa 48(%rsi), %xmm7 +; SSE42-NEXT: movq {{.*#+}} xmm8 = [0,1,4,5,8,9,12,13,0,0,0,0,0,0,0,0] +; SSE42-NEXT: pshufb %xmm8, %xmm6 +; SSE42-NEXT: pshufb %xmm8, %xmm4 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm6[0],xmm4[1],xmm6[1],xmm4[2],xmm6[2],xmm4[3],xmm6[3] +; SSE42-NEXT: pshufb %xmm8, %xmm2 +; SSE42-NEXT: pshufb %xmm8, %xmm0 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; SSE42-NEXT: pmaddwd %xmm4, %xmm0 +; SSE42-NEXT: pshufb %xmm8, %xmm7 +; SSE42-NEXT: pshufb %xmm8, %xmm5 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm7[0],xmm5[1],xmm7[1],xmm5[2],xmm7[2],xmm5[3],xmm7[3] +; SSE42-NEXT: pshufb %xmm8, %xmm3 +; SSE42-NEXT: pshufb %xmm8, %xmm1 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3] +; SSE42-NEXT: pmaddwd %xmm5, %xmm1 +; SSE42-NEXT: retq ; ; AVX1-LABEL: combine_pmaddwd_concat_add: ; AVX1: # %bb.0: @@ -195,6 +203,16 @@ define <8 x i32> @combine_pmaddwd_concat_add(ptr %px0, ptr %py0) { ; AVX2-NEXT: vpmaddwd 32(%rdi), %ymm0, %ymm0 ; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0 ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_pmaddwd_concat_add: +; AVX512: # %bb.0: +; AVX512-NEXT: vpxor %xmm0, %xmm0, %xmm0 +; AVX512-NEXT: vpblendw {{.*#+}} ymm1 = mem[0],ymm0[1],mem[2],ymm0[3],mem[4],ymm0[5],mem[6],ymm0[7],mem[8],ymm0[9],mem[10],ymm0[11],mem[12],ymm0[13],mem[14],ymm0[15] +; AVX512-NEXT: vpmaddwd (%rdi), %ymm1, %ymm1 +; AVX512-NEXT: vpblendw {{.*#+}} ymm0 = mem[0],ymm0[1],mem[2],ymm0[3],mem[4],ymm0[5],mem[6],ymm0[7],mem[8],ymm0[9],mem[10],ymm0[11],mem[12],ymm0[13],mem[14],ymm0[15] +; AVX512-NEXT: vpmaddwd 32(%rdi), %ymm0, %ymm0 +; AVX512-NEXT: vpaddd %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: retq %px1 = getelementptr inbounds nuw i8, ptr %px0, i64 16 %py1 = getelementptr inbounds nuw i8, ptr %py0, i64 16 %px2 = getelementptr inbounds nuw i8, ptr %px0, i64 32 @@ -241,6 +259,12 @@ define <4 x i32> @combine_pmaddwd_demandedelts(<8 x i16> %a0, <8 x i16> %a1) { ; AVX2-NEXT: vpmaddwd %xmm1, %xmm0, %xmm0 ; AVX2-NEXT: vpbroadcastd %xmm0, %xmm0 ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_pmaddwd_demandedelts: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmaddwd %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: vpbroadcastd %xmm0, %xmm0 +; AVX512-NEXT: retq %1 = shufflevector <8 x i16> %a0, <8 x i16> poison, <8 x i32> %2 = shufflevector <8 x i16> %a1, <8 x i16> poison, <8 x i32> %3 = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %1, <8 x i16> %2) @@ -283,10 +307,31 @@ define <4 x i32> @combine_pmaddwd_constant_nsw() { ; Constant folding PMADDWD was causing an infinite loop in the PCMPGT commuting between 2 constant values. define i1 @pmaddwd_pcmpgt_infinite_loop() { -; CHECK-LABEL: pmaddwd_pcmpgt_infinite_loop: -; CHECK: # %bb.0: -; CHECK-NEXT: movb $1, %al -; CHECK-NEXT: retq +; SSE-LABEL: pmaddwd_pcmpgt_infinite_loop: +; SSE: # %bb.0: +; SSE-NEXT: movb $1, %al +; SSE-NEXT: retq +; +; AVX1-LABEL: pmaddwd_pcmpgt_infinite_loop: +; AVX1: # %bb.0: +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: retq +; +; AVX2-LABEL: pmaddwd_pcmpgt_infinite_loop: +; AVX2: # %bb.0: +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: retq +; +; AVX512-LABEL: pmaddwd_pcmpgt_infinite_loop: +; AVX512: # %bb.0: +; AVX512-NEXT: vpxor %xmm0, %xmm0, %xmm0 +; AVX512-NEXT: vpbroadcastd {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] +; AVX512-NEXT: vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1 # [4294967288,4294967287,4294967286,4294967285] +; AVX512-NEXT: vpcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %k1 +; AVX512-NEXT: vpcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %k0 {%k1} +; AVX512-NEXT: kortestb %k0, %k0 +; AVX512-NEXT: sete %al +; AVX512-NEXT: retq %1 = tail call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> , <8 x i16> ) %2 = icmp eq <4 x i32> %1, %3 = select <4 x i1> %2, <4 x i32> , <4 x i32> zeroinitializer @@ -301,19 +346,12 @@ define i1 @pmaddwd_pcmpgt_infinite_loop() { ; If the shuffle matches, but there is no multiply, introduce a trivial multiply by 1. define <8 x i32> @sext_pairwise_add(<16 x i16> %x) { -; SSE2-LABEL: sext_pairwise_add: -; SSE2: # %bb.0: -; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] -; SSE2-NEXT: pmaddwd %xmm2, %xmm0 -; SSE2-NEXT: pmaddwd %xmm2, %xmm1 -; SSE2-NEXT: retq -; -; SSE41-LABEL: sext_pairwise_add: -; SSE41: # %bb.0: -; SSE41-NEXT: pmovsxbw {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] -; SSE41-NEXT: pmaddwd %xmm2, %xmm0 -; SSE41-NEXT: pmaddwd %xmm2, %xmm1 -; SSE41-NEXT: retq +; SSE-LABEL: sext_pairwise_add: +; SSE: # %bb.0: +; SSE-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] +; SSE-NEXT: pmaddwd %xmm2, %xmm0 +; SSE-NEXT: pmaddwd %xmm2, %xmm1 +; SSE-NEXT: retq ; ; AVX1-LABEL: sext_pairwise_add: ; AVX1: # %bb.0: @@ -328,6 +366,11 @@ define <8 x i32> @sext_pairwise_add(<16 x i16> %x) { ; AVX2: # %bb.0: ; AVX2-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ; AVX2-NEXT: retq +; +; AVX512-LABEL: sext_pairwise_add: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +; AVX512-NEXT: retq %1 = sext <16 x i16> %x to <16 x i32> %2 = shufflevector <16 x i32> %1, <16 x i32> poison, <8 x i32> %3 = shufflevector <16 x i32> %1, <16 x i32> poison, <8 x i32> @@ -356,6 +399,11 @@ define <8 x i32> @combine_with_mul(<16 x i16> %v) { ; AVX2: # %bb.0: # %bb1 ; AVX2-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1] ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_with_mul: +; AVX512: # %bb.0: # %bb1 +; AVX512-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1] +; AVX512-NEXT: retq bb1: %0 = sext <16 x i16> %v to <16 x i32> %1 = mul nsw <16 x i32> %0, @@ -386,6 +434,11 @@ define <8 x i32> @combine_with_shl(<16 x i16> %v) { ; AVX2: # %bb.0: # %bb1 ; AVX2-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1] ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_with_shl: +; AVX512: # %bb.0: # %bb1 +; AVX512-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1] +; AVX512-NEXT: retq bb1: %0 = sext <16 x i16> %v to <16 x i32> %1 = shl nsw <16 x i32> %0, @@ -415,21 +468,21 @@ define <8 x i32> @combine_with_shl_overflow(<16 x i16> %v) { ; SSE2-NEXT: paddd %xmm4, %xmm0 ; SSE2-NEXT: retq ; -; SSE41-LABEL: combine_with_shl_overflow: -; SSE41: # %bb.0: # %bb1 -; SSE41-NEXT: pxor %xmm2, %xmm2 -; SSE41-NEXT: pxor %xmm4, %xmm4 -; SSE41-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4],xmm1[4],xmm4[5],xmm1[5],xmm4[6],xmm1[6],xmm4[7],xmm1[7] -; SSE41-NEXT: pxor %xmm3, %xmm3 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1],xmm3[2],xmm1[2],xmm3[3],xmm1[3] -; SSE41-NEXT: phaddd %xmm4, %xmm3 -; SSE41-NEXT: pxor %xmm1, %xmm1 -; SSE41-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] -; SSE41-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3] -; SSE41-NEXT: phaddd %xmm1, %xmm2 -; SSE41-NEXT: movdqa %xmm2, %xmm0 -; SSE41-NEXT: movdqa %xmm3, %xmm1 -; SSE41-NEXT: retq +; SSE42-LABEL: combine_with_shl_overflow: +; SSE42: # %bb.0: # %bb1 +; SSE42-NEXT: pxor %xmm3, %xmm3 +; SSE42-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm1[4],xmm3[5],xmm1[5],xmm3[6],xmm1[6],xmm3[7],xmm1[7] +; SSE42-NEXT: pxor %xmm2, %xmm2 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3] +; SSE42-NEXT: phaddd %xmm3, %xmm2 +; SSE42-NEXT: pxor %xmm1, %xmm1 +; SSE42-NEXT: pxor %xmm3, %xmm3 +; SSE42-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7] +; SSE42-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] +; SSE42-NEXT: phaddd %xmm3, %xmm1 +; SSE42-NEXT: movdqa %xmm1, %xmm0 +; SSE42-NEXT: movdqa %xmm2, %xmm1 +; SSE42-NEXT: retq ; ; AVX1-LABEL: combine_with_shl_overflow: ; AVX1: # %bb.0: # %bb1 @@ -456,6 +509,15 @@ define <8 x i32> @combine_with_shl_overflow(<16 x i16> %v) { ; AVX2-NEXT: vphaddd %ymm0, %ymm1, %ymm0 ; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_with_shl_overflow: +; AVX512: # %bb.0: # %bb1 +; AVX512-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero +; AVX512-NEXT: vpslld $16, %zmm0, %zmm0 +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm1 +; AVX512-NEXT: vphaddd %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX512-NEXT: retq bb1: %0 = sext <16 x i16> %v to <16 x i32> %1 = shl nsw <16 x i32> %0, splat (i32 16) @@ -464,3 +526,5 @@ bb1: %4 = add <8 x i32> %2, %3 ret <8 x i32> %4 } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK: {{.*}} diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll index 1cdccaf110d30..8076f0a11762c 100644 --- a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll +++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll @@ -1858,215 +1858,182 @@ define <2 x i8> @to_f8e4m3fn_v2f16(<2 x half> %x) { ; CHECK-NEXT: .cfi_def_cfa_offset 48 ; CHECK-NEXT: pushq %rbx ; CHECK-NEXT: .cfi_def_cfa_offset 56 -; CHECK-NEXT: subq $72, %rsp -; CHECK-NEXT: .cfi_def_cfa_offset 128 +; CHECK-NEXT: subq $88, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 144 ; CHECK-NEXT: .cfi_offset %rbx, -56 ; CHECK-NEXT: .cfi_offset %r12, -48 ; CHECK-NEXT: .cfi_offset %r13, -40 ; CHECK-NEXT: .cfi_offset %r14, -32 ; CHECK-NEXT: .cfi_offset %r15, -24 ; CHECK-NEXT: .cfi_offset %rbp, -16 -; CHECK-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill ; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: callq frexpf@PLT +; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: movl $2, %ebx +; CHECK-NEXT: movl $2, %ebp +; CHECK-NEXT: subl %eax, %ebp +; CHECK-NEXT: cmpw $15, %bp +; CHECK-NEXT: movl $15, %eax +; CHECK-NEXT: cmovael %eax, %ebp +; CHECK-NEXT: cmpw $1, %bp +; CHECK-NEXT: movl %ebp, %r14d +; CHECK-NEXT: adcl $-1, %r14d ; CHECK-NEXT: callq __truncsfhf2@PLT -; CHECK-NEXT: pextrw $0, %xmm0, %r12d -; CHECK-NEXT: movl %r12d, %eax -; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00 +; CHECK-NEXT: pextrw $0, %xmm0, %r13d +; CHECK-NEXT: movl %r13d, %eax +; CHECK-NEXT: andl $1023, %eax # imm = 0x3FF +; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: leal 1024(%rax), %edi +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: movl %r14d, %ecx +; CHECK-NEXT: shrl %cl, %eax +; CHECK-NEXT: movl $1, %r15d +; CHECK-NEXT: movl $1, %edx +; CHECK-NEXT: shll %cl, %edx +; CHECK-NEXT: decl %edx +; CHECK-NEXT: xorl %esi, %esi +; CHECK-NEXT: movl %edi, %r14d +; CHECK-NEXT: testw %dx, %r14w +; CHECK-NEXT: setne %sil +; CHECK-NEXT: movl %ebp, %ecx +; CHECK-NEXT: shrl %cl, %r14d +; CHECK-NEXT: movl %r14d, %r12d +; CHECK-NEXT: andl $1, %r12d +; CHECK-NEXT: orl %esi, %r12d +; CHECK-NEXT: andl %eax, %r12d +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: cmpw $1, %bp ; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: pextrw $0, %xmm0, %r15d -; CHECK-NEXT: movl %r15d, %ecx -; CHECK-NEXT: andl $32767, %ecx # imm = 0x7FFF -; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400 -; CHECK-NEXT: cmovael %r15d, %r12d -; CHECK-NEXT: cmovael %ecx, %eax -; CHECK-NEXT: shrl $10, %eax -; CHECK-NEXT: leal -12(%rax), %edx -; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400 ; CHECK-NEXT: psrld $16, %xmm0 ; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill -; CHECK-NEXT: cmovael %eax, %edx -; CHECK-NEXT: addl $-14, %edx -; CHECK-NEXT: andl $33791, %r12d # imm = 0x83FF -; CHECK-NEXT: orl $14336, %r12d # imm = 0x3800 -; CHECK-NEXT: addl $-31744, %ecx # imm = 0x8400 -; CHECK-NEXT: movzwl %cx, %eax -; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: cmpl $33792, %eax # imm = 0x8400 -; CHECK-NEXT: cmovbel %ecx, %edx -; CHECK-NEXT: movq %rdx, %r14 -; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill -; CHECK-NEXT: cmovbel %r15d, %r12d +; CHECK-NEXT: cmovbl %eax, %r12d ; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: callq frexpf@PLT +; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: subl %eax, %ebx +; CHECK-NEXT: cmpw $15, %bx +; CHECK-NEXT: movl $15, %eax +; CHECK-NEXT: cmovael %eax, %ebx +; CHECK-NEXT: cmpw $1, %bx +; CHECK-NEXT: movl %ebx, %ebp +; CHECK-NEXT: adcl $-1, %ebp ; CHECK-NEXT: callq __truncsfhf2@PLT -; CHECK-NEXT: pextrw $0, %xmm0, %ebp -; CHECK-NEXT: movl %ebp, %eax -; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00 -; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: pextrw $0, %xmm0, %ebx -; CHECK-NEXT: movl %ebx, %r9d -; CHECK-NEXT: andl $32767, %r9d # imm = 0x7FFF -; CHECK-NEXT: cmpl $1024, %r9d # imm = 0x400 -; CHECK-NEXT: cmovael %ebx, %ebp -; CHECK-NEXT: cmovael %r9d, %eax -; CHECK-NEXT: shrl $10, %eax -; CHECK-NEXT: leal -12(%rax), %esi -; CHECK-NEXT: cmpl $1024, %r9d # imm = 0x400 -; CHECK-NEXT: cmovael %eax, %esi -; CHECK-NEXT: movl $2, %eax -; CHECK-NEXT: movl $2, %edx -; CHECK-NEXT: subl %r14d, %edx -; CHECK-NEXT: cmpw $15, %dx -; CHECK-NEXT: movl $15, %r13d -; CHECK-NEXT: cmovael %r13d, %edx -; CHECK-NEXT: cmpw $1, %dx -; CHECK-NEXT: movl %edx, %ecx -; CHECK-NEXT: adcl $-1, %ecx -; CHECK-NEXT: movl %r12d, %r10d -; CHECK-NEXT: andl $1023, %r10d # imm = 0x3FF -; CHECK-NEXT: leal 1024(%r10), %edi -; CHECK-NEXT: movl %edi, %r14d -; CHECK-NEXT: shrl %cl, %r14d -; CHECK-NEXT: movl $1, %r8d -; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx -; CHECK-NEXT: shll %cl, %r8d -; CHECK-NEXT: decl %r8d -; CHECK-NEXT: xorl %r11d, %r11d -; CHECK-NEXT: testw %r8w, %di -; CHECK-NEXT: setne %r11b -; CHECK-NEXT: movl %edx, %ecx -; CHECK-NEXT: shrl %cl, %edi -; CHECK-NEXT: movl %edi, %r8d -; CHECK-NEXT: andl $1, %r8d -; CHECK-NEXT: orl %r11d, %r8d -; CHECK-NEXT: movl $1, %r11d -; CHECK-NEXT: andl %r14d, %r8d -; CHECK-NEXT: cmpw $1, %dx -; CHECK-NEXT: movl $0, %edx -; CHECK-NEXT: cmovbl %edx, %r8d -; CHECK-NEXT: addl $-14, %esi -; CHECK-NEXT: andl $33791, %ebp # imm = 0x83FF -; CHECK-NEXT: orl $14336, %ebp # imm = 0x3800 -; CHECK-NEXT: addl $-31744, %r9d # imm = 0x8400 -; CHECK-NEXT: movzwl %r9w, %ecx -; CHECK-NEXT: cmpl $33792, %ecx # imm = 0x8400 -; CHECK-NEXT: cmovbel %edx, %esi -; CHECK-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill -; CHECK-NEXT: cmovbel %ebx, %ebp -; CHECK-NEXT: subl %esi, %eax -; CHECK-NEXT: cmpw $15, %ax -; CHECK-NEXT: cmovael %r13d, %eax -; CHECK-NEXT: cmpw $1, %ax -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: adcl $-1, %ecx -; CHECK-NEXT: movl %ebp, %edx +; CHECK-NEXT: pextrw $0, %xmm0, %eax +; CHECK-NEXT: movl %eax, %edx ; CHECK-NEXT: andl $1023, %edx # imm = 0x3FF -; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill -; CHECK-NEXT: leal 1024(%rdx), %r13d -; CHECK-NEXT: movl %r13d, %edx -; CHECK-NEXT: shrl %cl, %edx -; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx -; CHECK-NEXT: shll %cl, %r11d -; CHECK-NEXT: decl %r11d -; CHECK-NEXT: xorl %r9d, %r9d -; CHECK-NEXT: testw %r11w, %r13w -; CHECK-NEXT: setne %r9b -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: shrl %cl, %r13d -; CHECK-NEXT: movl %r13d, %r14d -; CHECK-NEXT: andl $1, %r14d -; CHECK-NEXT: orl %r9d, %r14d -; CHECK-NEXT: andl %edx, %r14d -; CHECK-NEXT: cmpw $1, %ax -; CHECK-NEXT: movl $0, %ecx -; CHECK-NEXT: cmovbl %ecx, %r14d -; CHECK-NEXT: addl %edi, %r8d -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpw $8, %r8w -; CHECK-NEXT: cmovgel %ecx, %r8d -; CHECK-NEXT: movl $0, %esi -; CHECK-NEXT: setge %al -; CHECK-NEXT: shrl $8, %r15d -; CHECK-NEXT: andl $128, %r15d -; CHECK-NEXT: leal (%r15,%rax,8), %eax -; CHECK-NEXT: orl %r8d, %eax -; CHECK-NEXT: shrl $7, %r10d -; CHECK-NEXT: movl %r10d, %ecx +; CHECK-NEXT: leal 1024(%rdx), %esi +; CHECK-NEXT: movl %esi, %edi +; CHECK-NEXT: movl %ebp, %ecx +; CHECK-NEXT: shrl %cl, %edi +; CHECK-NEXT: shll %cl, %r15d +; CHECK-NEXT: decl %r15d +; CHECK-NEXT: xorl %r8d, %r8d +; CHECK-NEXT: testw %r15w, %si +; CHECK-NEXT: setne %r8b +; CHECK-NEXT: movl %ebx, %ecx +; CHECK-NEXT: shrl %cl, %esi +; CHECK-NEXT: movl %esi, %ecx ; CHECK-NEXT: andl $1, %ecx -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: testb $63, %r12b -; CHECK-NEXT: setne %dl -; CHECK-NEXT: orl %ecx, %edx -; CHECK-NEXT: shrl $6, %r12d -; CHECK-NEXT: andl %edx, %r12d -; CHECK-NEXT: addl %r10d, %r12d -; CHECK-NEXT: xorl %ecx, %ecx +; CHECK-NEXT: orl %r8d, %ecx +; CHECK-NEXT: andl %edi, %ecx +; CHECK-NEXT: cmpw $1, %bx +; CHECK-NEXT: movl $0, %r8d +; CHECK-NEXT: cmovbl %r8d, %ecx +; CHECK-NEXT: addl %r14d, %r12d +; CHECK-NEXT: xorl %edi, %edi ; CHECK-NEXT: cmpw $8, %r12w -; CHECK-NEXT: cmovgel %esi, %r12d -; CHECK-NEXT: setge %cl -; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload -; CHECK-NEXT: leal (%rsi,%rcx), %edx -; CHECK-NEXT: leal 48(,%rdx,8), %edx -; CHECK-NEXT: orl %r15d, %r12d -; CHECK-NEXT: orl %edx, %r12d -; CHECK-NEXT: leal 6(%rsi,%rcx), %ecx -; CHECK-NEXT: testw %cx, %cx -; CHECK-NEXT: cmovlel %eax, %r12d -; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: xorps %xmm1, %xmm1 -; CHECK-NEXT: ucomiss %xmm1, %xmm0 -; CHECK-NEXT: cmovnel %r12d, %r15d -; CHECK-NEXT: cmovpl %r12d, %r15d -; CHECK-NEXT: movl $127, %r12d -; CHECK-NEXT: cmovpl %r12d, %r15d -; CHECK-NEXT: movzbl %r15b, %r15d -; CHECK-NEXT: addl %r13d, %r14d -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpw $8, %r14w -; CHECK-NEXT: movl $0, %edi -; CHECK-NEXT: cmovgel %edi, %r14d -; CHECK-NEXT: setge %al -; CHECK-NEXT: shrl $8, %ebx -; CHECK-NEXT: andl $128, %ebx -; CHECK-NEXT: leal (%rbx,%rax,8), %eax -; CHECK-NEXT: orl %r14d, %eax -; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload +; CHECK-NEXT: cmovgel %r8d, %r12d +; CHECK-NEXT: movl $0, %r11d +; CHECK-NEXT: setge %dil +; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload +; CHECK-NEXT: pextrw $0, %xmm0, %r8d +; CHECK-NEXT: shrl $8, %r8d +; CHECK-NEXT: andl $128, %r8d +; CHECK-NEXT: leal (%r8,%rdi,8), %edi +; CHECK-NEXT: orl %r12d, %edi +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; CHECK-NEXT: shrl $7, %r10d +; CHECK-NEXT: movl %r10d, %r9d +; CHECK-NEXT: movq %r10, %rbx +; CHECK-NEXT: andl $1, %r9d +; CHECK-NEXT: xorl %r10d, %r10d +; CHECK-NEXT: testb $63, %r13b +; CHECK-NEXT: setne %r10b +; CHECK-NEXT: orl %r9d, %r10d +; CHECK-NEXT: shrl $6, %r13d +; CHECK-NEXT: andl %r10d, %r13d +; CHECK-NEXT: addl %ebx, %r13d +; CHECK-NEXT: xorl %r9d, %r9d +; CHECK-NEXT: cmpw $8, %r13w +; CHECK-NEXT: cmovgel %r11d, %r13d +; CHECK-NEXT: setge %r9b +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; CHECK-NEXT: leal (%rbx,%r9), %r10d +; CHECK-NEXT: leal 48(,%r10,8), %r10d +; CHECK-NEXT: orl %r8d, %r13d +; CHECK-NEXT: orl %r10d, %r13d +; CHECK-NEXT: leal 6(%rbx,%r9), %r9d +; CHECK-NEXT: testw %r9w, %r9w +; CHECK-NEXT: cmovlel %edi, %r13d +; CHECK-NEXT: pxor %xmm0, %xmm0 +; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload +; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero +; CHECK-NEXT: ucomiss %xmm0, %xmm1 +; CHECK-NEXT: cmovnel %r13d, %r8d +; CHECK-NEXT: cmovpl %r13d, %r8d +; CHECK-NEXT: movl $127, %edi +; CHECK-NEXT: cmovpl %edi, %r8d +; CHECK-NEXT: movzbl %r8b, %r8d +; CHECK-NEXT: addl %esi, %ecx +; CHECK-NEXT: xorl %r9d, %r9d +; CHECK-NEXT: cmpw $8, %cx +; CHECK-NEXT: cmovgel %r11d, %ecx +; CHECK-NEXT: setge %r9b +; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload +; CHECK-NEXT: pextrw $0, %xmm1, %esi +; CHECK-NEXT: shrl $8, %esi +; CHECK-NEXT: andl $128, %esi +; CHECK-NEXT: leal (%rsi,%r9,8), %r9d +; CHECK-NEXT: orl %ecx, %r9d ; CHECK-NEXT: shrl $7, %edx ; CHECK-NEXT: movl %edx, %ecx -; CHECK-NEXT: movq %rdx, %rsi ; CHECK-NEXT: andl $1, %ecx -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: testb $63, %bpl -; CHECK-NEXT: setne %dl -; CHECK-NEXT: orl %ecx, %edx -; CHECK-NEXT: shrl $6, %ebp -; CHECK-NEXT: andl %edx, %ebp -; CHECK-NEXT: addl %esi, %ebp +; CHECK-NEXT: xorl %r10d, %r10d +; CHECK-NEXT: testb $63, %al +; CHECK-NEXT: setne %r10b +; CHECK-NEXT: orl %ecx, %r10d +; CHECK-NEXT: shrl $6, %eax +; CHECK-NEXT: andl %r10d, %eax +; CHECK-NEXT: addl %edx, %eax ; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: cmpw $8, %bp -; CHECK-NEXT: cmovgel %edi, %ebp +; CHECK-NEXT: cmpw $8, %ax +; CHECK-NEXT: cmovgel %r11d, %eax ; CHECK-NEXT: setge %cl -; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload -; CHECK-NEXT: leal (%rsi,%rcx), %edx +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; CHECK-NEXT: leal (%r10,%rcx), %edx ; CHECK-NEXT: leal 48(,%rdx,8), %edx -; CHECK-NEXT: orl %ebx, %ebp -; CHECK-NEXT: orl %edx, %ebp -; CHECK-NEXT: leal 6(%rsi,%rcx), %ecx +; CHECK-NEXT: orl %esi, %eax +; CHECK-NEXT: orl %edx, %eax +; CHECK-NEXT: leal 6(%r10,%rcx), %ecx ; CHECK-NEXT: testw %cx, %cx -; CHECK-NEXT: cmovlel %eax, %ebp -; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: xorps %xmm1, %xmm1 -; CHECK-NEXT: ucomiss %xmm1, %xmm0 -; CHECK-NEXT: cmovnel %ebp, %ebx -; CHECK-NEXT: cmovpl %ebp, %ebx -; CHECK-NEXT: cmovpl %r12d, %ebx -; CHECK-NEXT: shll $8, %ebx -; CHECK-NEXT: orl %r15d, %ebx -; CHECK-NEXT: movd %ebx, %xmm0 -; CHECK-NEXT: addq $72, %rsp +; CHECK-NEXT: cmovlel %r9d, %eax +; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload +; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero +; CHECK-NEXT: ucomiss %xmm0, %xmm1 +; CHECK-NEXT: cmovnel %eax, %esi +; CHECK-NEXT: cmovpl %eax, %esi +; CHECK-NEXT: cmovpl %edi, %esi +; CHECK-NEXT: shll $8, %esi +; CHECK-NEXT: orl %r8d, %esi +; CHECK-NEXT: movd %esi, %xmm0 +; CHECK-NEXT: addq $88, %rsp ; CHECK-NEXT: .cfi_def_cfa_offset 56 ; CHECK-NEXT: popq %rbx ; CHECK-NEXT: .cfi_def_cfa_offset 48 @@ -2102,121 +2069,105 @@ define i8 @to_f8e5m2_from_f16(half %x) { ; CHECK-NEXT: .cfi_offset %rbx, -32 ; CHECK-NEXT: .cfi_offset %r14, -24 ; CHECK-NEXT: .cfi_offset %rbp, -16 -; CHECK-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill ; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: callq frexpf@PLT +; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r14d +; CHECK-NEXT: movl $-5, %eax +; CHECK-NEXT: subl %r14d, %eax +; CHECK-NEXT: cmpw $15, %ax +; CHECK-NEXT: movl $15, %ebx +; CHECK-NEXT: cmovbl %eax, %ebx +; CHECK-NEXT: cmpw $1, %bx +; CHECK-NEXT: movl %ebx, %ebp +; CHECK-NEXT: adcl $-1, %ebp ; CHECK-NEXT: callq __truncsfhf2@PLT -; CHECK-NEXT: pextrw $0, %xmm0, %edx -; CHECK-NEXT: movl %edx, %eax -; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00 -; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: pextrw $0, %xmm0, %ebx -; CHECK-NEXT: movl %ebx, %ecx -; CHECK-NEXT: andl $32767, %ecx # imm = 0x7FFF -; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400 -; CHECK-NEXT: cmovael %ebx, %edx -; CHECK-NEXT: cmovael %ecx, %eax -; CHECK-NEXT: shrl $10, %eax -; CHECK-NEXT: leal -12(%rax), %esi -; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400 -; CHECK-NEXT: cmovael %eax, %esi -; CHECK-NEXT: addl $-14, %esi -; CHECK-NEXT: andl $33791, %edx # imm = 0x83FF -; CHECK-NEXT: orl $14336, %edx # imm = 0x3800 -; CHECK-NEXT: addl $-31744, %ecx # imm = 0x8400 -; CHECK-NEXT: movzwl %cx, %eax -; CHECK-NEXT: xorl %edi, %edi -; CHECK-NEXT: cmpl $33792, %eax # imm = 0x8400 -; CHECK-NEXT: cmovbel %edi, %esi -; CHECK-NEXT: cmovbel %ebx, %edx -; CHECK-NEXT: movl $-5, %ecx -; CHECK-NEXT: subl %esi, %ecx -; CHECK-NEXT: cmpw $15, %cx -; CHECK-NEXT: movl $15, %eax -; CHECK-NEXT: cmovbl %ecx, %eax -; CHECK-NEXT: cmpw $1, %ax -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: adcl $-1, %ecx -; CHECK-NEXT: movl %edx, %r8d -; CHECK-NEXT: andl $1023, %r8d # imm = 0x3FF -; CHECK-NEXT: leal 1024(%r8), %r9d -; CHECK-NEXT: movl %r9d, %r10d -; CHECK-NEXT: shrl %cl, %r10d -; CHECK-NEXT: movl $1, %r11d -; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx -; CHECK-NEXT: shll %cl, %r11d -; CHECK-NEXT: decl %r11d -; CHECK-NEXT: xorl %ebp, %ebp -; CHECK-NEXT: testw %r11w, %r9w -; CHECK-NEXT: setne %bpl -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: shrl %cl, %r9d -; CHECK-NEXT: movl %r9d, %ecx -; CHECK-NEXT: andl $1, %ecx -; CHECK-NEXT: orl %ebp, %ecx -; CHECK-NEXT: andl %r10d, %ecx -; CHECK-NEXT: cmpw $1, %ax -; CHECK-NEXT: cmovbl %edi, %ecx -; CHECK-NEXT: addl %r9d, %ecx -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpw $4, %cx -; CHECK-NEXT: cmovgel %edi, %ecx -; CHECK-NEXT: setge %al -; CHECK-NEXT: shrl $8, %ebx -; CHECK-NEXT: andl $128, %ebx -; CHECK-NEXT: leal (%rbx,%rax,4), %eax -; CHECK-NEXT: orl %ecx, %eax -; CHECK-NEXT: shrl $8, %r8d -; CHECK-NEXT: movl %r8d, %ecx -; CHECK-NEXT: andl $1, %ecx +; CHECK-NEXT: pextrw $0, %xmm0, %eax +; CHECK-NEXT: movl %eax, %edx +; CHECK-NEXT: andl $1023, %edx # imm = 0x3FF +; CHECK-NEXT: leal 1024(%rdx), %esi +; CHECK-NEXT: movl %esi, %edi +; CHECK-NEXT: movl %ebp, %ecx +; CHECK-NEXT: shrl %cl, %edi +; CHECK-NEXT: movl $1, %r8d +; CHECK-NEXT: shll %cl, %r8d +; CHECK-NEXT: decl %r8d ; CHECK-NEXT: xorl %r9d, %r9d -; CHECK-NEXT: testb $127, %dl +; CHECK-NEXT: testw %r8w, %si ; CHECK-NEXT: setne %r9b -; CHECK-NEXT: orl %ecx, %r9d -; CHECK-NEXT: shrl $7, %edx -; CHECK-NEXT: andl %r9d, %edx -; CHECK-NEXT: addl %r8d, %edx +; CHECK-NEXT: movl %ebx, %ecx +; CHECK-NEXT: shrl %cl, %esi +; CHECK-NEXT: movl %esi, %r8d +; CHECK-NEXT: andl $1, %r8d +; CHECK-NEXT: orl %r9d, %r8d +; CHECK-NEXT: andl %edi, %r8d ; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: cmpw $4, %dx -; CHECK-NEXT: cmovgel %edi, %edx -; CHECK-NEXT: setge %cl -; CHECK-NEXT: leal (%rsi,%rcx), %edi -; CHECK-NEXT: leal 56(,%rdi,4), %edi -; CHECK-NEXT: movl %ebx, %ebp -; CHECK-NEXT: orl %edx, %ebp -; CHECK-NEXT: orl %edi, %ebp -; CHECK-NEXT: leal 14(%rsi,%rcx), %ecx -; CHECK-NEXT: testw %cx, %cx -; CHECK-NEXT: cmovlel %eax, %ebp -; CHECK-NEXT: cmpw $4, %dx +; CHECK-NEXT: cmpw $1, %bx +; CHECK-NEXT: cmovbl %ecx, %r8d +; CHECK-NEXT: addl %esi, %r8d +; CHECK-NEXT: xorl %esi, %esi +; CHECK-NEXT: cmpw $4, %r8w +; CHECK-NEXT: cmovgel %ecx, %r8d +; CHECK-NEXT: setge %sil +; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload +; CHECK-NEXT: pextrw $0, %xmm1, %ebx +; CHECK-NEXT: shrl $8, %ebx +; CHECK-NEXT: andl $128, %ebx +; CHECK-NEXT: leal (%rbx,%rsi,4), %esi +; CHECK-NEXT: orl %r8d, %esi +; CHECK-NEXT: shrl $8, %edx +; CHECK-NEXT: movl %edx, %edi +; CHECK-NEXT: andl $1, %edi +; CHECK-NEXT: xorl %r8d, %r8d +; CHECK-NEXT: testb $127, %al +; CHECK-NEXT: setne %r8b +; CHECK-NEXT: orl %edi, %r8d +; CHECK-NEXT: shrl $7, %eax +; CHECK-NEXT: andl %r8d, %eax +; CHECK-NEXT: addl %edx, %eax +; CHECK-NEXT: xorl %edx, %edx +; CHECK-NEXT: cmpw $4, %ax +; CHECK-NEXT: cmovgel %ecx, %eax +; CHECK-NEXT: setge %dl +; CHECK-NEXT: leal (%r14,%rdx), %ecx +; CHECK-NEXT: leal 56(,%rcx,4), %edi +; CHECK-NEXT: movl %ebx, %ecx +; CHECK-NEXT: orl %eax, %ecx +; CHECK-NEXT: orl %edi, %ecx +; CHECK-NEXT: leal 14(%r14,%rdx), %edx +; CHECK-NEXT: testw %dx, %dx +; CHECK-NEXT: cmovlel %esi, %ecx +; CHECK-NEXT: cmpw $4, %ax ; CHECK-NEXT: setge %al -; CHECK-NEXT: cmpw $30, %cx -; CHECK-NEXT: sete %dl -; CHECK-NEXT: andb %al, %dl -; CHECK-NEXT: cmpw $31, %cx +; CHECK-NEXT: cmpw $30, %dx +; CHECK-NEXT: sete %sil +; CHECK-NEXT: andb %al, %sil +; CHECK-NEXT: cmpw $31, %dx ; CHECK-NEXT: setge %al -; CHECK-NEXT: orb %dl, %al -; CHECK-NEXT: leal 124(%rbx), %r14d +; CHECK-NEXT: orb %sil, %al +; CHECK-NEXT: leal 124(%rbx), %ebp ; CHECK-NEXT: testb %al, %al -; CHECK-NEXT: cmovnel %r14d, %ebp -; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill -; CHECK-NEXT: xorps %xmm1, %xmm1 -; CHECK-NEXT: ucomiss %xmm1, %xmm0 -; CHECK-NEXT: cmovnel %ebp, %ebx -; CHECK-NEXT: cmovpl %ebp, %ebx -; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-NEXT: cmovnel %ebp, %ecx +; CHECK-NEXT: xorps %xmm2, %xmm2 +; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload +; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero +; CHECK-NEXT: ucomiss %xmm2, %xmm0 +; CHECK-NEXT: cmovnel %ecx, %ebx +; CHECK-NEXT: cmovpl %ecx, %ebx +; CHECK-NEXT: movdqa %xmm1, %xmm0 +; CHECK-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 -; CHECK-NEXT: cmovnel %ebx, %r14d -; CHECK-NEXT: cmovpl %ebx, %r14d -; CHECK-NEXT: xorps %xmm0, %xmm0 -; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload -; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero -; CHECK-NEXT: ucomiss %xmm0, %xmm1 +; CHECK-NEXT: cmovnel %ebx, %ebp +; CHECK-NEXT: cmovpl %ebx, %ebp +; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload +; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero +; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: ucomiss %xmm1, %xmm0 ; CHECK-NEXT: movl $126, %eax -; CHECK-NEXT: cmovnpl %r14d, %eax +; CHECK-NEXT: cmovnpl %ebp, %eax ; CHECK-NEXT: # kill: def $al killed $al killed $eax ; CHECK-NEXT: addq $32, %rsp ; CHECK-NEXT: .cfi_def_cfa_offset 32 diff --git a/llvm/test/CodeGen/X86/implicit-null-check-debugloc.ll b/llvm/test/CodeGen/X86/implicit-null-check-debugloc.ll new file mode 100644 index 0000000000000..8eadabcdd0bb7 --- /dev/null +++ b/llvm/test/CodeGen/X86/implicit-null-check-debugloc.ll @@ -0,0 +1,33 @@ +; RUN: llc -mtriple=x86_64-linux-gnu -enable-implicit-null-checks \ +; RUN: -stop-after=implicit-null-checks -o - %s | FileCheck %s + +; ImplicitNullChecks must preserve the folded load's debug location on the +; resulting FAULTING_OP, otherwise the faulting instruction loses its source +; attribution in the DWARF line table. + +; CHECK: [[LOC:![0-9]+]] = !DILocation(line: 4 +; CHECK: FAULTING_OP {{.*}}debug-location [[LOC]] :: (load (s32) from %ir.p) + +define i32 @f(ptr %p) !dbg !4 { +entry: + %nn = icmp eq ptr %p, null + br i1 %nn, label %null, label %notnull, !make.implicit !0 + +notnull: + %v = load i32, ptr %p, !dbg !7 + ret i32 %v + +null: + unreachable +} + +!llvm.dbg.cu = !{!1} +!llvm.module.flags = !{!2} + +!0 = !{} +!1 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, emissionKind: FullDebug) +!2 = !{i32 2, !"Debug Info Version", i32 3} +!3 = !DIFile(filename: "repro.c", directory: "/") +!4 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !1) +!5 = !DISubroutineType(types: !{}) +!7 = !DILocation(line: 4, column: 10, scope: !4) diff --git a/llvm/test/CodeGen/X86/llvm.frexp.ll b/llvm/test/CodeGen/X86/llvm.frexp.ll index d14d737a5ca29..3410fd5169c9a 100644 --- a/llvm/test/CodeGen/X86/llvm.frexp.ll +++ b/llvm/test/CodeGen/X86/llvm.frexp.ll @@ -5,36 +5,13 @@ define { half, i32 } @test_frexp_f16_i32(half %a) nounwind { ; X64-LABEL: test_frexp_f16_i32: ; X64: # %bb.0: -; X64-NEXT: subq $24, %rsp -; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill +; X64-NEXT: pushq %rax ; X64-NEXT: callq __extendhfsf2@PLT -; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpf@PLT ; X64-NEXT: callq __truncsfhf2@PLT -; X64-NEXT: pextrw $0, %xmm0, %ecx -; X64-NEXT: movl %ecx, %eax -; X64-NEXT: andl $31744, %eax # imm = 0x7C00 -; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload -; X64-NEXT: pextrw $0, %xmm0, %edx -; X64-NEXT: movl %edx, %esi -; X64-NEXT: andl $32767, %esi # imm = 0x7FFF -; X64-NEXT: cmpl $1024, %esi # imm = 0x400 -; X64-NEXT: cmovael %edx, %ecx -; X64-NEXT: cmovael %esi, %eax -; X64-NEXT: shrl $10, %eax -; X64-NEXT: leal -12(%rax), %edi -; X64-NEXT: cmpl $1024, %esi # imm = 0x400 -; X64-NEXT: cmovael %eax, %edi -; X64-NEXT: addl $-14, %edi -; X64-NEXT: andl $33791, %ecx # imm = 0x83FF -; X64-NEXT: orl $14336, %ecx # imm = 0x3800 -; X64-NEXT: addl $-31744, %esi # imm = 0x8400 -; X64-NEXT: movzwl %si, %esi -; X64-NEXT: xorl %eax, %eax -; X64-NEXT: cmpl $33792, %esi # imm = 0x8400 -; X64-NEXT: cmoval %edi, %eax -; X64-NEXT: cmovbel %edx, %ecx -; X64-NEXT: pinsrw $0, %ecx, %xmm0 -; X64-NEXT: addq $24, %rsp +; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax +; X64-NEXT: popq %rcx ; X64-NEXT: retq ; ; WIN32-LABEL: test_frexp_f16_i32: @@ -64,26 +41,12 @@ define { half, i32 } @test_frexp_f16_i32(half %a) nounwind { define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind { ; X64-LABEL: test_frexp_f16_i32_only_use_fract: ; X64: # %bb.0: -; X64-NEXT: subq $24, %rsp -; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill +; X64-NEXT: pushq %rax ; X64-NEXT: callq __extendhfsf2@PLT -; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpf@PLT ; X64-NEXT: callq __truncsfhf2@PLT -; X64-NEXT: pextrw $0, %xmm0, %eax -; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload -; X64-NEXT: pextrw $0, %xmm0, %ecx -; X64-NEXT: movl %ecx, %edx -; X64-NEXT: andl $32767, %edx # imm = 0x7FFF -; X64-NEXT: cmpl $1024, %edx # imm = 0x400 -; X64-NEXT: cmovael %ecx, %eax -; X64-NEXT: andl $33791, %eax # imm = 0x83FF -; X64-NEXT: orl $14336, %eax # imm = 0x3800 -; X64-NEXT: addl $-31744, %edx # imm = 0x8400 -; X64-NEXT: movzwl %dx, %edx -; X64-NEXT: cmpl $33792, %edx # imm = 0x8400 -; X64-NEXT: cmovbel %ecx, %eax -; X64-NEXT: pinsrw $0, %eax, %xmm0 -; X64-NEXT: addq $24, %rsp +; X64-NEXT: popq %rax ; X64-NEXT: retq ; ; WIN32-LABEL: test_frexp_f16_i32_only_use_fract: @@ -110,29 +73,12 @@ define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind { define i32 @test_frexp_f16_i32_only_use_exp(half %a) nounwind { ; X64-LABEL: test_frexp_f16_i32_only_use_exp: ; X64: # %bb.0: -; X64-NEXT: subq $24, %rsp -; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill +; X64-NEXT: pushq %rax ; X64-NEXT: callq __extendhfsf2@PLT -; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 -; X64-NEXT: callq __truncsfhf2@PLT -; X64-NEXT: pextrw $0, %xmm0, %eax -; X64-NEXT: andl $31744, %eax # imm = 0x7C00 -; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload -; X64-NEXT: pextrw $0, %xmm0, %ecx -; X64-NEXT: andl $32767, %ecx # imm = 0x7FFF -; X64-NEXT: cmpl $1024, %ecx # imm = 0x400 -; X64-NEXT: cmovael %ecx, %eax -; X64-NEXT: shrl $10, %eax -; X64-NEXT: leal -12(%rax), %edx -; X64-NEXT: cmpl $1024, %ecx # imm = 0x400 -; X64-NEXT: cmovael %eax, %edx -; X64-NEXT: addl $-14, %edx -; X64-NEXT: addl $-31744, %ecx # imm = 0x8400 -; X64-NEXT: movzwl %cx, %ecx -; X64-NEXT: xorl %eax, %eax -; X64-NEXT: cmpl $33792, %ecx # imm = 0x8400 -; X64-NEXT: cmoval %edx, %eax -; X64-NEXT: addq $24, %rsp +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpf@PLT +; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax +; X64-NEXT: popq %rcx ; X64-NEXT: retq ; ; WIN32-LABEL: test_frexp_f16_i32_only_use_exp: diff --git a/llvm/test/MC/Disassembler/X86/x86-64-instruction-length.txt b/llvm/test/MC/Disassembler/X86/x86-64-instruction-length.txt new file mode 100644 index 0000000000000..cd441eca022c0 --- /dev/null +++ b/llvm/test/MC/Disassembler/X86/x86-64-instruction-length.txt @@ -0,0 +1,5 @@ +# RUN: llvm-mc --disassemble %s -triple=x86_64 2>&1 | FileCheck %s + +## 15 redundant operand-size (0x66) prefixes + NOP = 16 bytes, over the limit. +# CHECK: warning: invalid instruction encoding +0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x90 diff --git a/llvm/test/MC/ELF/size-expression-must-be-absolute.s b/llvm/test/MC/ELF/size-expression-must-be-absolute.s new file mode 100644 index 0000000000000..769df52d9bb44 --- /dev/null +++ b/llvm/test/MC/ELF/size-expression-must-be-absolute.s @@ -0,0 +1,6 @@ +// RUN: not --crash llvm-mc -triple=x86_64 -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s + +a: b: +.size a, b + +// CHECK: LLVM ERROR: size expression must be absolute diff --git a/llvm/test/MC/X86/check-end-of-data-region.s b/llvm/test/MC/X86/check-end-of-data-region.s index 50f5dab73d352..f0cf67bf7ed32 100644 --- a/llvm/test/MC/X86/check-end-of-data-region.s +++ b/llvm/test/MC/X86/check-end-of-data-region.s @@ -5,4 +5,4 @@ foo: .long 0 -// CHECK-ERROR: LLVM ERROR: Data region not terminated +// CHECK-ERROR: LLVM ERROR: data region not terminated diff --git a/llvm/test/Object/coff-invalid.test b/llvm/test/Object/coff-invalid.test index da5d687c6e208..d7b0f348b3028 100644 --- a/llvm/test/Object/coff-invalid.test +++ b/llvm/test/Object/coff-invalid.test @@ -10,4 +10,4 @@ SECTIONS-NEXT: VirtualAddress: 0x1000000 RUN: not --crash llvm-readobj -r %p/Inputs/invalid-bad-section-address.coff 2>&1 | \ RUN: FileCheck %s -CHECK: Sections with relocations should have an address of 0 +CHECK: sections with relocations should have an address of 0 diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll index ab80e6cbd797c..871914d7987f4 100644 --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -pass-remarks=attributor -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=REMARKS,REMARKS-TUNIT --implicit-check-not=remark +; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -pass-remarks=attributor -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=REMARKS,REMARKS-CGSCC --implicit-check-not=remark target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -16,10 +18,22 @@ define void @load_wholly_unreachable() { ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. %a = load i32, ptr null ret void } +define void @load_undef_pointer() { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CHECK-LABEL: define {{[^@]+}}@load_undef_pointer +; CHECK-SAME: () #[[ATTR0]] { +; CHECK-NEXT: unreachable +; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be undef is undefined behavior; replacing with 'unreachable'. + %a = load i32, ptr undef + ret void +} + define void @load_wholly_unreachable_volatile() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@load_wholly_unreachable_volatile @@ -37,6 +51,8 @@ define void @loads_wholly_unreachable() { ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. %a = load i32, ptr null %b = load i32, ptr null ret void @@ -53,6 +69,7 @@ define void @load_single_bb_unreachable(i1 %cond) { ; CHECK: e: ; CHECK-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t, label %e t: %b = load i32, ptr null @@ -93,6 +110,7 @@ define void @load_null_propagated() { ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Memory access through a pointer known to be call is undefined behavior; replacing with 'unreachable'. %ptr = call ptr @ret_null() %a = load i32, ptr %ptr ret void @@ -106,6 +124,7 @@ define void @store_wholly_unreachable() { ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. store i32 5, ptr null ret void } @@ -131,6 +150,7 @@ define void @store_single_bb_unreachable(i1 %cond) { ; CHECK: e: ; CHECK-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t, label %e t: store i32 5, ptr null @@ -171,6 +191,7 @@ define void @store_null_propagated() { ; CGSCC-NEXT: [[PTR:%.*]] = call noalias align 4294967296 ptr @ret_null() #[[ATTR11:[0-9]+]] ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Memory access through a pointer known to be call is undefined behavior; replacing with 'unreachable'. %ptr = call ptr @ret_null() store i32 5, ptr %ptr ret void @@ -189,6 +210,7 @@ define void @atomicrmw_wholly_unreachable() { ; CGSCC-SAME: () #[[ATTR6:[0-9]+]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. %a = atomicrmw add ptr null, i32 1 acquire ret void } @@ -212,6 +234,7 @@ define void @atomicrmw_single_bb_unreachable(i1 %cond) { ; CGSCC: e: ; CGSCC-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t, label %e t: %a = atomicrmw add ptr null, i32 1 acquire @@ -253,6 +276,7 @@ define void @atomicrmw_null_propagated() { ; CGSCC-NEXT: [[A:%.*]] = atomicrmw add ptr [[PTR]], i32 1 acquire, align 4 ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Memory access through a pointer known to be call is undefined behavior; replacing with 'unreachable'. %ptr = call ptr @ret_null() %a = atomicrmw add ptr %ptr, i32 1 acquire ret void @@ -271,6 +295,7 @@ define void @atomiccmpxchg_wholly_unreachable() { ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. %a = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic ret void } @@ -294,6 +319,7 @@ define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) { ; CGSCC: e: ; CGSCC-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t, label %e t: %a = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic @@ -335,6 +361,7 @@ define void @atomiccmpxchg_null_propagated() { ; CGSCC-NEXT: [[A:%.*]] = cmpxchg ptr [[PTR]], i32 2, i32 3 acq_rel monotonic, align 4 ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Memory access through a pointer known to be call is undefined behavior; replacing with 'unreachable'. %ptr = call ptr @ret_null() %a = cmpxchg ptr %ptr, i32 2, i32 3 acq_rel monotonic ret void @@ -363,6 +390,7 @@ define i32 @cond_br_on_undef() { ; CGSCC: e: ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Branch condition known to be undef is undefined behavior; replacing with 'unreachable'. br i1 undef, label %t, label %e t: ret i32 1 @@ -387,6 +415,7 @@ define void @cond_br_on_undef2(i1 %cond) { ; CHECK: e1: ; CHECK-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Branch condition known to be undef is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t1, label %e1 t1: br i1 undef, label %t2, label %e2 @@ -427,6 +456,7 @@ define void @cond_br_on_undef_interproc() { ; CGSCC: e: ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Branch condition known to be call is undefined behavior; replacing with 'unreachable'. %cond = call i1 @ret_undef() br i1 %cond, label %t, label %e t: @@ -473,6 +503,7 @@ define void @cond_br_on_undef_interproc2() { ; CGSCC: e: ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Branch condition known to be call is undefined behavior; replacing with 'unreachable'. %cond = call i1 @ret_undef2() br i1 %cond, label %t, label %e t: @@ -502,6 +533,7 @@ define i32 @cond_br_on_undef3() { ; CGSCC: e: ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Branch condition known to be icmp is undefined behavior; replacing with 'unreachable'. %cond = icmp ne i32 1, undef br i1 %cond, label %t, label %e t: @@ -556,6 +588,7 @@ define internal i32 @callee(i1 %C, ptr %A) { ; CGSCC: F: ; CGSCC-NEXT: ret i32 1 ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. entry: %A.0 = load i32, ptr null br i1 %C, label %T, label %F @@ -715,6 +748,7 @@ define void @arg_nonnull_violation1_1() { ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_1 known to be null is undefined behavior; replacing with 'unreachable'. call void @arg_nonnull_1(ptr null) ret void } @@ -730,6 +764,7 @@ define void @arg_nonnull_violation1_2() { ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_1_noundef_1 known to be null is undefined behavior; replacing with 'unreachable'. call void @arg_nonnull_1_noundef_1(ptr null) ret void } @@ -746,6 +781,7 @@ define void @arg_nonnull_violation2_1(i1 %c) { ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_1 known to be null is undefined behavior; replacing with 'unreachable'. %mustnull = select i1 %c, ptr null, ptr null call void @arg_nonnull_1(ptr %mustnull) ret void @@ -762,6 +798,7 @@ define void @arg_nonnull_violation2_2(i1 %c) { ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_1_noundef_1 known to be null is undefined behavior; replacing with 'unreachable'. %mustnull = select i1 %c, ptr null, ptr null call void @arg_nonnull_1_noundef_1(ptr %mustnull) ret void @@ -797,6 +834,12 @@ define void @arg_nonnull_violation3_1(i1 %c) { ; CGSCC: ret: ; CGSCC-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Argument 1 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 1 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. %ptr = alloca i32 br i1 %c, label %t, label %f t: @@ -844,6 +887,12 @@ define void @arg_nonnull_violation3_2(i1 %c) { ; CGSCC: ret: ; CGSCC-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Argument 1 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 1 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. %ptr = alloca i32 br i1 %c, label %t, label %f t: @@ -907,6 +956,7 @@ define noundef ptr @returned_noundef(i32 %c) { ; CHECK: ondefault: ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Value returned known to be undef is undefined behavior; replacing with 'unreachable'. switch i32 %c, label %ondefault [ i32 0, label %onzero i32 1, label %onone ] onzero: @@ -934,6 +984,8 @@ define nonnull noundef ptr @returned_nonnnull_noundef(i32 %c) { ; CHECK: ondefault: ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Value returned known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Value returned known to be undef is undefined behavior; replacing with 'unreachable'. switch i32 %c, label %ondefault [ i32 0, label %onzero i32 1, label %onone ] onzero: @@ -971,6 +1023,7 @@ define void @callsite_noundef_2() { ; CHECK-LABEL: define {{[^@]+}}@callsite_noundef_2() { ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of callee_ptr_arg known to be undef is undefined behavior; replacing with 'unreachable'. call void @callee_ptr_arg(ptr noundef undef) ret void } @@ -995,6 +1048,7 @@ define i32 @violate_noundef_nonpointer() { ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS-CGSCC: remark: {{.*}}: Argument 0 passed to parameter of argument_noundef1 known to be undef is undefined behavior; replacing with 'unreachable'. %ret = call i32 @argument_noundef1(i32 undef) ret i32 %ret } diff --git a/llvm/test/Transforms/Inline/X86/inline-target-cpu-i686.ll b/llvm/test/Transforms/Inline/X86/inline-target-cpu-i686.ll index 187278d1c9035..ef2eee0df87b2 100644 --- a/llvm/test/Transforms/Inline/X86/inline-target-cpu-i686.ll +++ b/llvm/test/Transforms/Inline/X86/inline-target-cpu-i686.ll @@ -16,5 +16,5 @@ define i32 @target_cpu_prescott_call_target_cpu_nocona() #1 { ret i32 %call } -attributes #0 = { nounwind "target-cpu"="nocona" } +attributes #0 = { nounwind "target-cpu"="nocona" "target-features"="-cx16" } attributes #1 = { nounwind "target-cpu"="prescott" } diff --git a/llvm/test/Transforms/Inline/X86/inline-target-cpu-x86_64.ll b/llvm/test/Transforms/Inline/X86/inline-target-cpu-x86_64.ll index e6693a637d820..a264f90dc28c8 100644 --- a/llvm/test/Transforms/Inline/X86/inline-target-cpu-x86_64.ll +++ b/llvm/test/Transforms/Inline/X86/inline-target-cpu-x86_64.ll @@ -51,4 +51,4 @@ attributes #0 = { nounwind "target-cpu"="x86-64" } attributes #1 = { nounwind "target-cpu"="k8" } attributes #2 = { nounwind "target-cpu"="nehalem" } attributes #3 = { nounwind "target-cpu"="goldmont" } -attributes #4 = { nounwind "target-cpu"="nocona" "target-features"="-sse3" } +attributes #4 = { nounwind "target-cpu"="nocona" "target-features"="-sse3,-cx16" } diff --git a/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-opts-cmpne.ll b/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-opts-cmpne.ll index e803572a06523..11e6e0089293a 100644 --- a/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-opts-cmpne.ll +++ b/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-opts-cmpne.ll @@ -261,6 +261,88 @@ define @not_cmpne_wrong_xor_operand( %vec_a ret %not } +define @zext_cmpne_i8( %vec) #0 { +; CHECK-LABEL: define @zext_cmpne_i8( +; CHECK-SAME: [[VEC:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ZEXT:%.*]] = call @llvm.aarch64.sve.umin.u.nxv16i8( splat (i1 true), [[VEC]], splat (i8 1)) +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), %vec, zeroinitializer) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_zero_lhs_i8( %vec) #0 { +; CHECK-LABEL: define @zext_cmpne_zero_lhs_i8( +; CHECK-SAME: [[VEC:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP1:%.*]] = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), zeroinitializer, [[VEC]]) +; CHECK-NEXT: [[ZEXT:%.*]] = zext [[TMP1]] to +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), zeroinitializer, %vec) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_wide_i32( %vec) #0 { +; CHECK-LABEL: define @zext_cmpne_wide_i32( +; CHECK-SAME: [[VEC:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ZEXT:%.*]] = call @llvm.aarch64.sve.umin.u.nxv4i32( splat (i1 true), [[VEC]], splat (i32 1)) +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.wide.nxv4i32( splat (i1 true), %vec, zeroinitializer) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_non_ptrue( %vec, %pg) #0 { +; CHECK-LABEL: define @zext_cmpne_non_ptrue( +; CHECK-SAME: [[VEC:%.*]], [[PG:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call @llvm.aarch64.sve.cmpne.nxv16i8( [[PG]], [[VEC]], zeroinitializer) +; CHECK-NEXT: [[ZEXT:%.*]] = zext [[CMP]] to +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( %pg, %vec, zeroinitializer) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_nonzero_rhs( %vec) #0 { +; CHECK-LABEL: define @zext_cmpne_nonzero_rhs( +; CHECK-SAME: [[VEC:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), [[VEC]], splat (i8 1)) +; CHECK-NEXT: [[ZEXT:%.*]] = zext [[CMP]] to +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), %vec, splat (i8 1)) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_multiple_uses( %vec, %pg) #0 { +; CHECK-LABEL: define @zext_cmpne_multiple_uses( +; CHECK-SAME: [[VEC:%.*]], [[PG:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), [[VEC]], zeroinitializer) +; CHECK-NEXT: [[AND_1:%.*]] = and [[CMP]], [[PG]] +; CHECK-NEXT: call void (...) @llvm.fake.use( [[AND_1]]) +; CHECK-NEXT: [[ZEXT:%.*]] = call @llvm.aarch64.sve.umin.u.nxv16i8( splat (i1 true), [[VEC]], splat (i8 1)) +; CHECK-NEXT: [[ZEXT_1:%.*]] = zext [[CMP]] to +; CHECK-NEXT: call void (...) @llvm.fake.use( [[ZEXT_1]]) +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), %vec, zeroinitializer) + + %and.1 = and %cmp, %pg + call void (...) @llvm.fake.use( %and.1) + + %zext.0 = zext %cmp to + + %zext.1 = zext %cmp to + call void (...) @llvm.fake.use( %zext.1) + + ret %zext.0 +} + ; Cases that cannot be converted define @dupq_neg1() #0 { diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-with-predicate.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-with-predicate.ll index 1309a6bb268c3..6a73f63e41a2e 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-with-predicate.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-with-predicate.ll @@ -72,14 +72,14 @@ define i32 @pred_reduction(ptr %src, ptr %cond, i64 %N) #0 { ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP7]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = xor i1 [[TMP9]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP8:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = xor i1 [[TMP8]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP9]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: -; CHECK-TAILFOLD-NEXT: ret i32 [[TMP11]] +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP10]] ; entry: br label %for.body @@ -177,14 +177,14 @@ define i32 @pred_reduction_sext(ptr %src, ptr %cond, i64 %N) #0 { ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP7]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = xor i1 [[TMP9]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP8:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = xor i1 [[TMP8]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP9]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: -; CHECK-TAILFOLD-NEXT: ret i32 [[TMP11]] +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP10]] ; entry: br label %for.body @@ -294,14 +294,14 @@ define i32 @pred_reduction_dotprod(ptr %a, ptr %b, ptr %cond, i64 %N) #0 { ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP10]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = xor i1 [[TMP12]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP13]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = xor i1 [[TMP11]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP14:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: -; CHECK-TAILFOLD-NEXT: ret i32 [[TMP14]] +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP13]] ; entry: br label %for.body @@ -416,12 +416,12 @@ define i32 @pred_sub_reduction(ptr %a, ptr %b, ptr %cond, i64 %N) #0 { ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP10]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = xor i1 [[TMP12]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP13]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = xor i1 [[TMP11]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP15:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) -; CHECK-TAILFOLD-NEXT: [[TMP14:%.*]] = sub i32 0, [[TMP15]] +; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: [[TMP14:%.*]] = sub i32 0, [[TMP13]] ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: ; CHECK-TAILFOLD-NEXT: ret i32 [[TMP14]] @@ -660,14 +660,14 @@ define i32 @reduction_before_pred(ptr %src, ptr noalias %src_b, ptr %cond, i64 % ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE3]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[PARTIAL_REDUCE]], [[TMP9]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = xor i1 [[TMP11]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = xor i1 [[TMP10]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP11]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE3]]) +; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE3]]) ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: -; CHECK-TAILFOLD-NEXT: ret i32 [[TMP13]] +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP12]] ; entry: br label %for.body @@ -703,6 +703,117 @@ exit: ret i32 %sum.2 } +; Predicated reduction where the VPBlend has the previous accumulator +; as incoming value 0 and the reduction update as incoming value 1. +; Checks that the single use update value will be selected from either +; position rather than assuming it's always incoming value 0. +; Placing the update block (if.then) before for.body will ensure the +; update value comes second. +define i32 @pred_reduction_incoming_1(ptr %src, ptr %cond, i64 %N) #0 { +; CHECK-LABEL: define i32 @pred_reduction_incoming_1( +; CHECK-SAME: ptr [[SRC:%.*]], ptr [[COND:%.*]], i64 [[N:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i64 [[TMP0]], 5 +; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], [[TMP1]] +; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] +; CHECK: [[VECTOR_PH]]: +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[TMP0]], 4 +; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP2]], 1 +; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N]], [[TMP3]] +; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]] +; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] +; CHECK: [[VECTOR_BODY]]: +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[VECTOR_PH]] ], [ [[PARTIAL_REDUCE:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_PHI1:%.*]] = phi [ zeroinitializer, %[[VECTOR_PH]] ], [ [[PARTIAL_REDUCE6:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw i8, ptr [[COND]], i64 [[INDEX]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP4]], i64 [[TMP2]] +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load , ptr [[TMP4]], align 1 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load , ptr [[TMP5]], align 1 +; CHECK-NEXT: [[TMP12:%.*]] = icmp ne [[WIDE_LOAD]], zeroinitializer +; CHECK-NEXT: [[TMP13:%.*]] = icmp ne [[WIDE_LOAD2]], zeroinitializer +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[INDEX]] +; CHECK-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP14]], i64 [[TMP2]] +; CHECK-NEXT: [[WIDE_MASKED_LOAD4:%.*]] = call @llvm.masked.load.nxv16i8.p0(ptr align 1 [[TMP14]], [[TMP12]], poison) +; CHECK-NEXT: [[WIDE_MASKED_LOAD5:%.*]] = call @llvm.masked.load.nxv16i8.p0(ptr align 1 [[TMP15]], [[TMP13]], poison) +; CHECK-NEXT: [[TMP16:%.*]] = zext [[WIDE_MASKED_LOAD4]] to +; CHECK-NEXT: [[TMP17:%.*]] = select [[TMP12]], [[TMP16]], zeroinitializer +; CHECK-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP17]]) +; CHECK-NEXT: [[TMP18:%.*]] = zext [[WIDE_MASKED_LOAD5]] to +; CHECK-NEXT: [[TMP19:%.*]] = select [[TMP13]], [[TMP18]], zeroinitializer +; CHECK-NEXT: [[PARTIAL_REDUCE6]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI1]], [[TMP19]]) +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP3]] +; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] +; CHECK-NEXT: br i1 [[TMP20]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]] +; CHECK: [[MIDDLE_BLOCK]]: +; CHECK-NEXT: [[BIN_RDX:%.*]] = add [[PARTIAL_REDUCE6]], [[PARTIAL_REDUCE]] +; CHECK-NEXT: [[TMP21:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[BIN_RDX]]) +; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]] +; CHECK-NEXT: br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH]] +; CHECK: [[SCALAR_PH]]: +; +; CHECK-TAILFOLD-LABEL: define i32 @pred_reduction_incoming_1( +; CHECK-TAILFOLD-SAME: ptr [[SRC:%.*]], ptr [[COND:%.*]], i64 [[N:%.*]]) #[[ATTR0]] { +; CHECK-TAILFOLD-NEXT: [[ENTRY:.*:]] +; CHECK-TAILFOLD-NEXT: br label %[[VECTOR_PH:.*]] +; CHECK-TAILFOLD: [[VECTOR_PH]]: +; CHECK-TAILFOLD-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-TAILFOLD-NEXT: [[TMP1:%.*]] = shl nuw i64 [[TMP0]], 4 +; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 0, i64 [[N]]) +; CHECK-TAILFOLD-NEXT: br label %[[VECTOR_BODY:.*]] +; CHECK-TAILFOLD: [[VECTOR_BODY]]: +; CHECK-TAILFOLD-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] +; CHECK-TAILFOLD-NEXT: [[TMP4:%.*]] = phi [ [[ACTIVE_LANE_MASK_ENTRY]], %[[VECTOR_PH]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], %[[VECTOR_BODY]] ] +; CHECK-TAILFOLD-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[VECTOR_PH]] ], [ [[PARTIAL_REDUCE:%.*]], %[[VECTOR_BODY]] ] +; CHECK-TAILFOLD-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw i8, ptr [[COND]], i64 [[INDEX]] +; CHECK-TAILFOLD-NEXT: [[WIDE_MASKED_LOAD1:%.*]] = call @llvm.masked.load.nxv16i8.p0(ptr align 1 [[TMP5]], [[TMP4]], poison) +; CHECK-TAILFOLD-NEXT: [[TMP6:%.*]] = icmp ne [[WIDE_MASKED_LOAD1]], zeroinitializer +; CHECK-TAILFOLD-NEXT: [[TMP8:%.*]] = select [[TMP4]], [[TMP6]], zeroinitializer +; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[INDEX]] +; CHECK-TAILFOLD-NEXT: [[WIDE_MASKED_LOAD2:%.*]] = call @llvm.masked.load.nxv16i8.p0(ptr align 1 [[TMP9]], [[TMP8]], poison) +; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = zext [[WIDE_MASKED_LOAD2]] to +; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = select [[TMP8]], [[TMP10]], zeroinitializer +; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP11]]) +; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] +; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) +; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = xor i1 [[TMP12]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP13]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] +; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: +; CHECK-TAILFOLD-NEXT: [[TMP14:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] +; CHECK-TAILFOLD: [[EXIT]]: +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP14]] +; +entry: + br label %for.body + +if.then: + %arrayidx2 = getelementptr inbounds nuw i8, ptr %src, i64 %iv + %val = load i8, ptr %arrayidx2, align 1 + %conv = zext i8 %val to i32 + %add = add nsw i32 %sum, %conv + br label %for.inc + +for.body: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ] + %sum = phi i32 [ 0, %entry ], [ %sum.1, %for.inc ] + %arrayidx = getelementptr inbounds nuw i8, ptr %cond, i64 %iv + %c = load i8, ptr %arrayidx, align 1 + %tobool.not = icmp eq i8 %c, 0 + br i1 %tobool.not, label %for.inc, label %if.then + +for.inc: + %sum.1 = phi i32 [ %add, %if.then ], [ %sum, %for.body ] + %iv.next = add nuw nsw i64 %iv, 1 + %exitcond.not = icmp eq i64 %iv.next, %N + br i1 %exitcond.not, label %exit, label %for.body + +exit: + ret i32 %sum.1 +} + ; UTC_ARGS: --disable ; Negative test - expect not to generate a partial reduction as phi diff --git a/llvm/test/Transforms/LoopVectorize/early-exit-minmax-trip-count.ll b/llvm/test/Transforms/LoopVectorize/early-exit-minmax-trip-count.ll new file mode 100644 index 0000000000000..25a60cc14761a --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/early-exit-minmax-trip-count.ll @@ -0,0 +1,330 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6 +; RUN: opt -S -passes=loop-vectorize -enable-early-exit-vectorization -force-vector-width=4 %s | FileCheck %s + +; The loop should be vectorized. The vectorizer needs to prove +; (A umin B) u<= A to establish memory safety from the dereferenceable +; assumption. +; +; long n = umin(count, length); +; for (long i = 0; i < n; i++) +; if (ptr[i] == 0) return null; +; ... +define ptr @deref_umin_trip_count_and_length(i32 %length, ptr %ptr, i64 %count) #0 { +; CHECK-LABEL: define ptr @deref_umin_trip_count_and_length( +; CHECK-SAME: i32 [[LENGTH:%.*]], ptr [[PTR:%.*]], i64 [[COUNT:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[COUNT_CHECK:%.*]] = icmp ne i64 [[COUNT]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[COUNT_CHECK]]) +; CHECK-NEXT: [[LENGTH_64:%.*]] = zext i32 [[LENGTH]] to i64 +; CHECK-NEXT: [[TRIP_COUNT:%.*]] = call i64 @llvm.umin.i64(i64 [[COUNT]], i64 [[LENGTH_64]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8), "dereferenceable"(ptr [[PTR]], i64 [[LENGTH_64]]) ] +; CHECK-NEXT: [[LENGTH_CHECK:%.*]] = icmp ne i32 [[LENGTH]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[LENGTH_CHECK]]) +; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TRIP_COUNT]], 4 +; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] +; CHECK: [[VECTOR_PH]]: +; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TRIP_COUNT]], 4 +; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TRIP_COUNT]], [[N_MOD_VF]] +; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] +; CHECK: [[VECTOR_BODY]]: +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY_INTERIM:.*]] ] +; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDEX]] +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP0]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] +; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]]) +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 +; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] +; CHECK-NEXT: br i1 [[TMP3]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[VECTOR_BODY_INTERIM]] +; CHECK: [[VECTOR_BODY_INTERIM]]: +; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK: [[MIDDLE_BLOCK]]: +; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TRIP_COUNT]], [[N_VEC]] +; CHECK-NEXT: br i1 [[CMP_N]], label %[[DEOPT:.*]], label %[[SCALAR_PH]] +; CHECK: [[VECTOR_EARLY_EXIT]]: +; CHECK-NEXT: br label %[[FOUND:.*]] +; CHECK: [[SCALAR_PH]]: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[FOUND]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[TRIP_COUNT]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[DEOPT]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK: [[FOUND]]: +; CHECK-NEXT: ret ptr null +; CHECK: [[DEOPT]]: +; CHECK-NEXT: unreachable +; +entry: + %count_check = icmp ne i64 %count, 0 + call void @llvm.assume(i1 %count_check) + %length.64 = zext i32 %length to i64 + %trip.count = call i64 @llvm.umin.i64(i64 %count, i64 %length.64) + call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8), "dereferenceable"(ptr %ptr, i64 %length.64) ] + %length_check = icmp ne i32 %length, 0 + call void @llvm.assume(i1 %length_check) + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %found, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp ult i64 %iv.next, %trip.count + br i1 %range_check, label %loop, label %deopt + +found: + ret ptr null + +deopt: + unreachable +} + +; The trip count is %c and the dereferenceable region is umin(%a, %b). +define i1 @deref_umin_all_operands_bounded(ptr %ptr, i64 %a, i64 %b, i64 %c) #0 { +; CHECK-LABEL: define i1 @deref_umin_all_operands_bounded( +; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[GUARD_A:%.*]] = icmp ule i64 [[C]], [[A]] +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_A]]) +; CHECK-NEXT: [[GUARD_B:%.*]] = icmp ule i64 [[C]], [[B]] +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_B]]) +; CHECK-NEXT: [[GUARD_POS:%.*]] = icmp ugt i64 [[C]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_POS]]) +; CHECK-NEXT: [[DEREF:%.*]] = call i64 @llvm.umin.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 [[DEREF]]) ] +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[EXIT_0:.*]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[C]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[EXIT_1:.*]] +; CHECK: [[EXIT_0]]: +; CHECK-NEXT: ret i1 true +; CHECK: [[EXIT_1]]: +; CHECK-NEXT: ret i1 false +; +entry: + %guard.a = icmp ule i64 %c, %a + call void @llvm.assume(i1 %guard.a) + %guard.b = icmp ule i64 %c, %b + call void @llvm.assume(i1 %guard.b) + %guard.pos = icmp ugt i64 %c, 0 + call void @llvm.assume(i1 %guard.pos) + %deref = call i64 @llvm.umin.i64(i64 %a, i64 %b) + call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %ptr, i64 %deref) ] + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %exit.0, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp ult i64 %iv.next, %c + br i1 %range_check, label %loop, label %exit.1 + +exit.0: + ret i1 true + +exit.1: + ret i1 false +} + +; Same as above, but the guards are written in swapped (uge) form. +define i1 @deref_umin_swapped_guards(ptr %ptr, i64 %a, i64 %b, i64 %c) #0 { +; CHECK-LABEL: define i1 @deref_umin_swapped_guards( +; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[GUARD_A:%.*]] = icmp uge i64 [[A]], [[C]] +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_A]]) +; CHECK-NEXT: [[GUARD_B:%.*]] = icmp uge i64 [[B]], [[C]] +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_B]]) +; CHECK-NEXT: [[GUARD_POS:%.*]] = icmp ugt i64 [[C]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_POS]]) +; CHECK-NEXT: [[DEREF:%.*]] = call i64 @llvm.umin.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 [[DEREF]]) ] +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[EXIT_0:.*]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[C]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[EXIT_1:.*]] +; CHECK: [[EXIT_0]]: +; CHECK-NEXT: ret i1 true +; CHECK: [[EXIT_1]]: +; CHECK-NEXT: ret i1 false +; +entry: + %guard.a = icmp uge i64 %a, %c + call void @llvm.assume(i1 %guard.a) + %guard.b = icmp uge i64 %b, %c + call void @llvm.assume(i1 %guard.b) + %guard.pos = icmp ugt i64 %c, 0 + call void @llvm.assume(i1 %guard.pos) + %deref = call i64 @llvm.umin.i64(i64 %a, i64 %b) + call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %ptr, i64 %deref) ] + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %exit.0, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp ult i64 %iv.next, %c + br i1 %range_check, label %loop, label %exit.1 + +exit.0: + ret i1 true + +exit.1: + ret i1 false +} + +; The trip count is a signed smin of the loop count and a sext'd length. Memory +; safety needs smin(%count, %length) s<= %length, which only the signed "any_of" +; min case proves (the removed unsigned umin fast-path could not reason about a +; signed smin at all). +define i1 @smin_signed_trip_count(i32 %length, ptr %ptr, i64 %count) #0 { +; CHECK-LABEL: define i1 @smin_signed_trip_count( +; CHECK-SAME: i32 [[LENGTH:%.*]], ptr [[PTR:%.*]], i64 [[COUNT:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[POSCHECK:%.*]] = icmp sgt i64 [[COUNT]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[POSCHECK]]) +; CHECK-NEXT: [[LENGTH_64:%.*]] = sext i32 [[LENGTH]] to i64 +; CHECK-NEXT: [[EXIT:%.*]] = call i64 @llvm.smin.i64(i64 [[COUNT]], i64 [[LENGTH_64]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8), "dereferenceable"(ptr [[PTR]], i64 [[LENGTH_64]]) ] +; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp sgt i32 [[LENGTH]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[NULL_CHECK]]) +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[EXIT_0:.*]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp slt i64 [[IV_NEXT]], [[EXIT]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[EXIT_1:.*]] +; CHECK: [[EXIT_0]]: +; CHECK-NEXT: ret i1 true +; CHECK: [[EXIT_1]]: +; CHECK-NEXT: ret i1 false +; +entry: + %poscheck = icmp sgt i64 %count, 0 + call void @llvm.assume(i1 %poscheck) + %length.64 = sext i32 %length to i64 + %exit = call i64 @llvm.smin.i64(i64 %count, i64 %length.64) + call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8), "dereferenceable"(ptr %ptr, i64 %length.64) ] + %null_check = icmp sgt i32 %length, 0 + call void @llvm.assume(i1 %null_check) + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %exit.0, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp slt i64 %iv.next, %exit + br i1 %range_check, label %loop, label %exit.1 + +exit.0: + ret i1 true + +exit.1: + ret i1 false +} + +; The dereferenceable size is umax(%length, %k) and the trip count is %length. +; Memory safety needs %length u<= umax(%length, %k), which only holds because +; %length is itself an operand of the umax ("any_of" max case). +define i1 @umax_deref_bound(i32 %length, ptr %ptr, i64 %k) #0 { +; CHECK-LABEL: define i1 @umax_deref_bound( +; CHECK-SAME: i32 [[LENGTH:%.*]], ptr [[PTR:%.*]], i64 [[K:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[POSCHECK:%.*]] = icmp sgt i64 [[K]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[POSCHECK]]) +; CHECK-NEXT: [[LENGTH_64:%.*]] = zext i32 [[LENGTH]] to i64 +; CHECK-NEXT: [[DEREF:%.*]] = call i64 @llvm.umax.i64(i64 [[LENGTH_64]], i64 [[K]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8), "dereferenceable"(ptr [[PTR]], i64 [[DEREF]]) ] +; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp ne i32 [[LENGTH]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[NULL_CHECK]]) +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[EXIT_0:.*]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[LENGTH_64]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[EXIT_1:.*]] +; CHECK: [[EXIT_0]]: +; CHECK-NEXT: ret i1 true +; CHECK: [[EXIT_1]]: +; CHECK-NEXT: ret i1 false +; +entry: + %poscheck = icmp sgt i64 %k, 0 + call void @llvm.assume(i1 %poscheck) + %length.64 = zext i32 %length to i64 + %deref = call i64 @llvm.umax.i64(i64 %length.64, i64 %k) + call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8), "dereferenceable"(ptr %ptr, i64 %deref) ] + %null_check = icmp ne i32 %length, 0 + call void @llvm.assume(i1 %null_check) + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %exit.0, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp ult i64 %iv.next, %length.64 + br i1 %range_check, label %loop, label %exit.1 + +exit.0: + ret i1 true + +exit.1: + ret i1 false +} + +attributes #0 = { nofree nosync } diff --git a/llvm/test/Transforms/LoopVectorize/early-exit-umin-trip-count.ll b/llvm/test/Transforms/LoopVectorize/early-exit-umin-trip-count.ll deleted file mode 100644 index 202c839e44aad..0000000000000 --- a/llvm/test/Transforms/LoopVectorize/early-exit-umin-trip-count.ll +++ /dev/null @@ -1,103 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6 -; RUN: opt -S -passes=loop-vectorize %s | FileCheck %s - -; The loop should be vectorized. The vectorizer needs to prove -; (A umin B) u<= A to establish memory safety from the dereferenceable -; assumption. -; -; long n = umin(count, length); -; for (long i = 0; i < n; i++) -; if (ptr[i] == 0) return null; -; ... -define ptr @main(i32 %length, ptr %ptr, i64 %0) #0 { -; CHECK-LABEL: define ptr @main( -; CHECK-SAME: i32 [[LENGTH:%.*]], ptr [[PTR:%.*]], i64 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[NULL_CHECK0:%.*]] = icmp eq i64 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[NULL_CHECK0]], label %[[DEOPT:.*]], label %[[PREHEADER:.*]] -; CHECK: [[PREHEADER]]: -; CHECK-NEXT: [[LENGTH_64:%.*]] = zext i32 [[LENGTH]] to i64 -; CHECK-NEXT: [[EXIT:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP0]], i64 [[LENGTH_64]]) -; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8), "dereferenceable"(ptr [[PTR]], i64 [[LENGTH_64]]) ] -; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i32 [[LENGTH]], 0 -; CHECK-NEXT: br i1 [[NULL_CHECK]], label %[[DEOPT]], label %[[SCALAR_PH1:.*]] -; CHECK: [[SCALAR_PH1]]: -; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[EXIT]], 4 -; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] -; CHECK: [[VECTOR_PH]]: -; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[EXIT]], 4 -; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[EXIT]], [[N_MOD_VF]] -; CHECK-NEXT: br label %[[LOOP1:.*]] -; CHECK: [[LOOP1]]: -; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY_INTERIM:.*]] ] -; CHECK-NEXT: [[ELEMENT_GEP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV1]] -; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[ELEMENT_GEP1]], align 1 -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer -; CHECK-NEXT: [[TMP3:%.*]] = freeze <4 x i1> [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP3]]) -; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[IV1]], 4 -; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] -; CHECK-NEXT: br i1 [[TMP4]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[VECTOR_BODY_INTERIM]] -; CHECK: [[VECTOR_BODY_INTERIM]]: -; CHECK-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[LOOP1]], !llvm.loop [[LOOP0:![0-9]+]] -; CHECK: [[MIDDLE_BLOCK]]: -; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[EXIT]], [[N_VEC]] -; CHECK-NEXT: br i1 [[CMP_N]], label %[[DEOPT_LOOPEXIT:.*]], label %[[SCALAR_PH]] -; CHECK: [[VECTOR_EARLY_EXIT]]: -; CHECK-NEXT: br label %[[FOUND:.*]] -; CHECK: [[SCALAR_PH]]: -; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[SCALAR_PH1]] ] -; CHECK-NEXT: br label %[[LOOP:.*]] -; CHECK: [[LOOP]]: -; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ], [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ] -; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] -; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 -; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 -; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[FOUND]], label %[[LATCH]] -; CHECK: [[LATCH]]: -; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 -; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[EXIT]] -; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[DEOPT_LOOPEXIT]], !llvm.loop [[LOOP3:![0-9]+]] -; CHECK: [[FOUND]]: -; CHECK-NEXT: ret ptr null -; CHECK: [[DEOPT_LOOPEXIT]]: -; CHECK-NEXT: br label %[[DEOPT]] -; CHECK: [[DEOPT]]: -; CHECK-NEXT: unreachable -; -entry: - %null_check0 = icmp eq i64 %0, 0 - br i1 %null_check0, label %deopt, label %preheader - -preheader: ; preds = %entry - %length.64 = zext i32 %length to i64 - %exit = call i64 @llvm.umin.i64(i64 %0, i64 %length.64) - call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8), "dereferenceable"(ptr %ptr, i64 %length.64) ] - %null_check = icmp eq i32 %length, 0 - br i1 %null_check, label %deopt, label %loop - -loop: ; preds = %latch, %preheader - %iv = phi i64 [ %iv.next, %latch ], [ 0, %preheader ] - %element_gep = getelementptr i8, ptr %ptr, i64 %iv - %element = load i8, ptr %element_gep, align 1 - %found_check = icmp eq i8 %element, 0 - br i1 %found_check, label %found, label %latch - -latch: ; preds = %loop - %iv.next = add i64 %iv, 1 - %range_check = icmp ult i64 %iv.next, %exit - br i1 %range_check, label %loop, label %deopt - -found: ; preds = %loop - ret ptr null - -deopt: ; preds = %latch, %preheader - unreachable -} - -declare i64 @llvm.umin.i64(i64, i64) - -declare void @llvm.assume(i1 noundef) - -attributes #0 = { nofree nosync } - diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-uniquing.cpp b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-uniquing.cpp index 17833fe3a7d2d..5358fa8a658bd 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-uniquing.cpp +++ b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-uniquing.cpp @@ -252,15 +252,15 @@ void foo() { // CHECK:0x00000064: "u" // CHECK:0x00000066: "AnonC" // CHECK:0x0000006c: "(anonymous namespace)" -// CHECK:0x00000082: "llvm DWARFLinkerParallel library version " -// CHECK:0x000000ac: "__artificial_type_unit" -// CHECK:0x000000c3: "" -// CHECK:0x000000c4: "AliasForS" -// CHECK:0x000000ce: "C" -// CHECK:0x000000d0: "N" -// CHECK:0x000000d2: "Nested" -// CHECK:0x000000d9: "S" -// CHECK:0x000000db: "U" +// CHECK:0x00000082: "llvm DWARFLinkerParallel library version +// CHECK: "__artificial_type_unit" +// CHECK: "" +// CHECK: "AliasForS" +// CHECK: "C" +// CHECK: "N" +// CHECK: "Nested" +// CHECK: "S" +// CHECK: "U" // CHECK:.apple_names diff --git a/llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp b/llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp index 7f53f5322f548..08a32390140d6 100644 --- a/llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp +++ b/llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp @@ -52,14 +52,14 @@ class AMDGPUSelectionDAGTest : public testing::Test { void SetUp() override { std::string Error; - Triple TargetTriple("amdgcn--amdpal"); + Triple TargetTriple("amdgpu10.10--amdpal"); const Target *T = TargetRegistry::lookupTarget(TargetTriple, Error); if (!T) GTEST_SKIP(); TargetOptions Options; - TM = std::unique_ptr(T->createTargetMachine( - TargetTriple, "gfx1010", "", Options, std::nullopt)); + TM = std::unique_ptr( + T->createTargetMachine(TargetTriple, "", "", Options, std::nullopt)); if (!TM) GTEST_SKIP(); diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp index 19b3161dd0313..da3714a620b90 100644 --- a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp @@ -67,7 +67,7 @@ body: | } std::unique_ptr AMDGPUGISelMITest::createTargetMachine() const { - Triple TargetTriple("amdgcn-amd-amdhsa"); + Triple TargetTriple("amdgpu9.00-amd-amdhsa"); std::string Error; const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); if (!T) @@ -75,7 +75,7 @@ std::unique_ptr AMDGPUGISelMITest::createTargetMachine() const { TargetOptions Options; return std::unique_ptr( - T->createTargetMachine(TargetTriple, "gfx900", "", Options, std::nullopt, + T->createTargetMachine(TargetTriple, "", "", Options, std::nullopt, std::nullopt, CodeGenOptLevel::Aggressive)); } diff --git a/llvm/unittests/CodeGen/RematerializerTest.cpp b/llvm/unittests/CodeGen/RematerializerTest.cpp index b29f06ca83892..b37760a57580e 100644 --- a/llvm/unittests/CodeGen/RematerializerTest.cpp +++ b/llvm/unittests/CodeGen/RematerializerTest.cpp @@ -102,7 +102,7 @@ class RematerializerTest : public CodeGenTestBase { #endif } - void SetUp() override { setUpImpl("amdgcn--", "gfx950", ""); } + void SetUp() override { setUpImpl("amdgpu9.50--", "", ""); } using RematerializerTestFn = std::function; diff --git a/llvm/unittests/MC/AMDGPU/Disassembler.cpp b/llvm/unittests/MC/AMDGPU/Disassembler.cpp index a6c4b98915aca..c0017f79427cc 100644 --- a/llvm/unittests/MC/AMDGPU/Disassembler.cpp +++ b/llvm/unittests/MC/AMDGPU/Disassembler.cpp @@ -32,8 +32,8 @@ static const char *symbolLookupCallback(void *DisInfo, uint64_t ReferenceValue, return nullptr; } -static constexpr char TripleName[] = "amdgcn--amdpal"; -static constexpr char CPUName[] = "gfx1030"; +static constexpr char TripleName[] = "amdgpu10.30--amdpal"; +static constexpr char CPUName[] = ""; // Basic smoke test. TEST(AMDGPUDisassembler, Basic) { diff --git a/llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp b/llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp index 4edd0f1227378..2123eefed347a 100644 --- a/llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp +++ b/llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp @@ -43,9 +43,9 @@ createTargetMachine(std::string TStr, StringRef CPU, StringRef FS) { } TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) { - for (auto Triple : - {"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) { - auto TM = createTargetMachine(Triple, "gfx1010", "+wavefrontsize64"); + for (auto Triple : {"amdgpu10.10-amd-", "amdgpu10.10-amd-amdhsa", + "amdgpu10.10-amd-amdpal"}) { + auto TM = createTargetMachine(Triple, "", "+wavefrontsize64"); if (TM) { const auto &MRI = TM->getMCRegisterInfo(); // Wave64 Dwarf register mapping test numbers @@ -63,9 +63,9 @@ TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) { } TEST(AMDGPUDwarfRegMappingTests, TestWave32DwarfRegMapping) { - for (auto Triple : - {"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) { - auto TM = createTargetMachine(Triple, "gfx1010", "+wavefrontsize32"); + for (auto Triple : {"amdgpu10.10-amd-", "amdgpu10.10-amd-amdhsa", + "amdgpu10.10-amd-amdpal"}) { + auto TM = createTargetMachine(Triple, "", "+wavefrontsize32"); if (TM) { const auto &MRI = TM->getMCRegisterInfo(); // Wave32 Dwarf register mapping test numbers diff --git a/llvm/unittests/MI/LiveIntervalTest.cpp b/llvm/unittests/MI/LiveIntervalTest.cpp index 45b8aeb72b598..0581d84fd0709 100644 --- a/llvm/unittests/MI/LiveIntervalTest.cpp +++ b/llvm/unittests/MI/LiveIntervalTest.cpp @@ -42,7 +42,7 @@ void initLLVM() { /// unittests, we go for "AMDGPU" to be able to test normal and subregister /// liveranges. std::unique_ptr createTargetMachine() { - Triple TargetTriple("amdgcn--"); + Triple TargetTriple("amdgpu9.00--"); std::string Error; const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); if (!T) @@ -50,7 +50,7 @@ std::unique_ptr createTargetMachine() { TargetOptions Options; return std::unique_ptr( - T->createTargetMachine(TargetTriple, "gfx900", "", Options, std::nullopt, + T->createTargetMachine(TargetTriple, "", "", Options, std::nullopt, std::nullopt, CodeGenOptLevel::Aggressive)); } diff --git a/llvm/unittests/MIR/MachineMetadata.cpp b/llvm/unittests/MIR/MachineMetadata.cpp index 8960a3a107d10..f58a3cac1bb0f 100644 --- a/llvm/unittests/MIR/MachineMetadata.cpp +++ b/llvm/unittests/MIR/MachineMetadata.cpp @@ -441,8 +441,8 @@ CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, !al } TEST_F(MachineMetadataTest, MMSlotTrackerAMDGPU) { - auto TM = createTargetMachine(Triple::normalize("amdgcn-amd-amdhsa"), - "gfx1010", ""); + auto TM = + createTargetMachine(Triple::normalize("amdgpu10.10-amd-amdhsa"), "", ""); if (!TM) GTEST_SKIP(); diff --git a/llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp b/llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp index 86c296feed792..83b47531a96fb 100644 --- a/llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp +++ b/llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp @@ -31,7 +31,7 @@ class AMDGPUMCExprTest : public AMDGPUTestBase { AMDGPUMCExprTest() { - TM = createAMDGPUTargetMachine("amdgcn--amdpal", "gfx1010", ""); + TM = createAMDGPUTargetMachine("amdgpu10.10--amdpal", "", ""); LLVMCtx = std::make_unique(); M = std::make_unique("Module", *LLVMCtx); diff --git a/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp b/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp index d1570e3986188..9bb526e7c85f5 100644 --- a/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp +++ b/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp @@ -275,7 +275,7 @@ static const char *printSubReg(const TargetRegisterInfo &TRI, unsigned SubReg) { } TEST_F(AMDGPUTestBase, TestReverseComposeSubRegIndices) { - auto TM = createAMDGPUTargetMachine("amdgcn-amd-", "gfx900", ""); + auto TM = createAMDGPUTargetMachine("amdgpu9.00-amd-", "", ""); if (!TM) return; GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), @@ -352,7 +352,7 @@ TEST_F(AMDGPUTestBase, TestReverseComposeSubRegIndices) { TEST_F(AMDGPUTestBase, TestGetNamedOperandIdx) { std::unique_ptr TM = - createAMDGPUTargetMachine("amdgcn-amd-", "gfx900", ""); + createAMDGPUTargetMachine("amdgpu9.00-amd-", "", ""); if (!TM) return; const MCInstrInfo *MCII = TM->getMCInstrInfo(); diff --git a/llvm/unittests/Target/AMDGPU/CSETest.cpp b/llvm/unittests/Target/AMDGPU/CSETest.cpp index 382f23906e92d..a302a3e372d45 100644 --- a/llvm/unittests/Target/AMDGPU/CSETest.cpp +++ b/llvm/unittests/Target/AMDGPU/CSETest.cpp @@ -16,7 +16,7 @@ using namespace llvm; TEST_F(AMDGPUTestBase, TestCSEForRegisterClassOrBankAndLLT) { - auto TM = createAMDGPUTargetMachine("amdgcn-amd-", "gfx1100", ""); + auto TM = createAMDGPUTargetMachine("amdgpu11.00-amd-", "", ""); if (!TM) GTEST_SKIP(); diff --git a/llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp b/llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp index ec8ed7f15b35a..fe3cafe270fbe 100644 --- a/llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp +++ b/llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp @@ -13,9 +13,9 @@ using namespace llvm; TEST_F(AMDGPUTestBase, TestWave64DwarfRegMapping) { - for (auto Triple : - {"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) { - auto TM = createAMDGPUTargetMachine(Triple, "gfx1010", "+wavefrontsize64"); + for (auto Triple : {"amdgpu10.10-amd-", "amdgpu10.10-amd-amdhsa", + "amdgpu10.10-amd-amdpal"}) { + auto TM = createAMDGPUTargetMachine(Triple, "", "+wavefrontsize64"); if (TM) { GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), std::string(TM->getTargetFeatureString()), *TM); @@ -53,9 +53,9 @@ TEST_F(AMDGPUTestBase, TestWave64DwarfRegMapping) { } TEST_F(AMDGPUTestBase, TestWave32DwarfRegMapping) { - for (auto Triple : - {"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) { - auto TM = createAMDGPUTargetMachine(Triple, "gfx1010", "+wavefrontsize32"); + for (auto Triple : {"amdgpu10.10-amd-", "amdgpu10.10-amd-amdhsa", + "amdgpu10.10-amd-amdpal"}) { + auto TM = createAMDGPUTargetMachine(Triple, "", "+wavefrontsize32"); if (TM) { GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), std::string(TM->getTargetFeatureString()), *TM); diff --git a/llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp b/llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp index 8034bf6561d86..4f02ab9e482a3 100644 --- a/llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp +++ b/llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp @@ -14,7 +14,7 @@ using namespace llvm; TEST_F(AMDGPUTestBase, ExecMayBeModifiedBeforeAnyUse) { - auto TM = createAMDGPUTargetMachine("amdgcn-amd-", "gfx906", ""); + auto TM = createAMDGPUTargetMachine("amdgpu9.06-amd-", "", ""); if (!TM) GTEST_SKIP(); diff --git a/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp b/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp index d907ee269a448..c0acf9e7dde4f 100644 --- a/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp +++ b/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp @@ -22,7 +22,7 @@ using namespace llvm; class GCNRegPressureTest : public llvm::CodeGenTestBase { public: - void SetUp() override { setUpImpl("amdgcn--", "gfx908", ""); } + void SetUp() override { setUpImpl("amdgpu9.08--", "", ""); } }; TEST_F(GCNRegPressureTest, DownwardTrackerEndOnDbgVal) { diff --git a/llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp b/llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp index ec3d465891467..0cd41faf6e5ad 100644 --- a/llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp +++ b/llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp @@ -18,7 +18,7 @@ using namespace llvm; class LiveRegUnitsTest : public AMDGPUCodeGenTestBase { public: - void SetUp() override { setUpImpl("amdgcn-amd-", "gfx1200", ""); } + void SetUp() override { setUpImpl("amdgpu12.00-amd-", "", ""); } }; TEST_F(LiveRegUnitsTest, TestVGPRBlockLoadStore) { diff --git a/llvm/unittests/Target/AMDGPU/PALMetadata.cpp b/llvm/unittests/Target/AMDGPU/PALMetadata.cpp index 64537921ec4a6..38d3f8b37cce2 100644 --- a/llvm/unittests/Target/AMDGPU/PALMetadata.cpp +++ b/llvm/unittests/Target/AMDGPU/PALMetadata.cpp @@ -34,7 +34,7 @@ class PALMetadata : public AMDGPUTestBase { AMDGPUPALMetadata MD; PALMetadata() { - TM = createAMDGPUTargetMachine("amdgcn--amdpal", "gfx1010", ""); + TM = createAMDGPUTargetMachine("amdgpu10.10--amdpal", "", ""); Ctx = std::make_unique(); M = std::make_unique("Module", *Ctx); diff --git a/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp b/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp index e61ef1d56c0a3..5b98e34c2a91e 100644 --- a/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp +++ b/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp @@ -55,7 +55,7 @@ TEST_F(AMDGPUTestBase, NewValueIsConservativelyDivergent) { ASSERT_TRUE(F); auto TM = - createAMDGPUTargetMachine("amdgcn-amd-", "gfx1010", "+wavefrontsize32"); + createAMDGPUTargetMachine("amdgpu10.10-amd-", "", "+wavefrontsize32"); ASSERT_TRUE(TM); TargetTransformInfo TTI = TM->getTargetTransformInfo(*F); diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/LegalityTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/LegalityTest.cpp index 586f846caf267..e5ddf53b598c1 100644 --- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/LegalityTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/LegalityTest.cpp @@ -137,7 +137,8 @@ define void @foo(ptr %ptr, <2 x float> %vec2, <3 x float> %vec3, i8 %arg, float auto *Sel1 = cast(&*It++); llvm::sandboxir::InstrMaps IMaps; - sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps); + sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps, + sandboxir::SchedDirection::BottomUp); const auto &Result = Legality.canVectorize({St0, St1}, /*SkipScheduling=*/true); EXPECT_TRUE(isa(Result)); @@ -289,7 +290,8 @@ define void @foo(ptr %ptr) { auto *St1 = cast(&*It++); llvm::sandboxir::InstrMaps IMaps; - sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps); + sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps, + sandboxir::SchedDirection::BottomUp); { // Can vectorize St0,St1. const auto &Result = Legality.canVectorize({St0, St1}); @@ -325,7 +327,8 @@ define void @foo() { sandboxir::Context Ctx(C); llvm::sandboxir::InstrMaps IMaps; - sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps); + sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE( Matches(Legality.createLegalityResult(), "Widen")); EXPECT_TRUE(Matches(Legality.createLegalityResult( diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SchedulerTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SchedulerTest.cpp index 0c756e6b705a0..7f7f303a90f51 100644 --- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SchedulerTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SchedulerTest.cpp @@ -241,20 +241,23 @@ define void @foo(ptr %ptr, i8 %v0, i8 %v1) { { // Schedule all instructions in sequence. - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({Ret})); EXPECT_TRUE(Sched.trySchedule({S1})); EXPECT_TRUE(Sched.trySchedule({S0})); } { // Skip instructions. - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({Ret})); EXPECT_TRUE(Sched.trySchedule({S0})); } { // Try invalid scheduling. Dependency S0->S1. - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({Ret})); EXPECT_FALSE(Sched.trySchedule({S0, S1})); } @@ -285,8 +288,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) { { Ctx.save(); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); - Sched.setDirection(sandboxir::SchedDirection::TopDown); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::TopDown); EXPECT_TRUE(Sched.trySchedule({L0, L1})); EXPECT_TRUE(Sched.trySchedule({S0, S1})); EXPECT_TRUE(Sched.trySchedule({Ret})); @@ -294,8 +297,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) { } { Ctx.save(); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); - Sched.setDirection(sandboxir::SchedDirection::TopDown); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::TopDown); EXPECT_TRUE(Sched.trySchedule({L0, L1})); EXPECT_TRUE(Sched.trySchedule({S1})); EXPECT_TRUE(Sched.trySchedule({S0})); @@ -304,8 +307,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) { } { Ctx.save(); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); - Sched.setDirection(sandboxir::SchedDirection::TopDown); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::TopDown); EXPECT_TRUE(Sched.trySchedule({L0, L1})); EXPECT_TRUE(Sched.trySchedule({S0})); EXPECT_TRUE(Sched.trySchedule({S1})); @@ -315,8 +318,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) { } { Ctx.save(); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); - Sched.setDirection(sandboxir::SchedDirection::TopDown); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::TopDown); EXPECT_TRUE(Sched.trySchedule({L0})); EXPECT_TRUE(Sched.trySchedule({L1})); EXPECT_FALSE(Sched.trySchedule({S0, S2})); @@ -326,8 +329,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) { } { Ctx.save(); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); - Sched.setDirection(sandboxir::SchedDirection::TopDown); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::TopDown); EXPECT_TRUE(Sched.trySchedule({L1})); EXPECT_TRUE(Sched.trySchedule({L0})); EXPECT_TRUE(Sched.trySchedule({S0, S1})); @@ -336,8 +339,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) { } { Ctx.save(); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); - Sched.setDirection(sandboxir::SchedDirection::TopDown); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::TopDown); // Dependent instrs. EXPECT_FALSE(Sched.trySchedule({L0, L1, S0, S1})); EXPECT_FALSE(Sched.trySchedule({L0, L1, S0})); @@ -374,7 +377,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) { auto *S1 = cast(&*It++); auto *Ret = cast(&*It++); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({Ret})); EXPECT_TRUE(Sched.trySchedule({S0, S1})); EXPECT_TRUE(Sched.trySchedule({L0, L1})); @@ -407,7 +411,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, i8 %arg) { auto *S1 = cast(&*It++); auto *Ret = cast(&*It++); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({Ret})); EXPECT_TRUE(Sched.trySchedule({S0, S1})); EXPECT_TRUE(Sched.trySchedule({L0, L1})); @@ -457,7 +462,8 @@ define void @foo(ptr %ptr, i16 %arg) { auto *S0 = cast(&*It++); auto *S1 = cast(&*It++); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({S0, S1})); EXPECT_TRUE(Sched.trySchedule({Zext0, Zext1})); EXPECT_TRUE(Sched.trySchedule({Shl0, Shl1})); @@ -496,7 +502,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, ptr noalias %ptr2) { auto *S0 = cast(&*It++); auto *S1 = cast(&*It++); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({S0, S1})); EXPECT_TRUE(Sched.trySchedule({Add0, Add1})); EXPECT_TRUE(Sched.trySchedule({L0, L1})); @@ -533,7 +540,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, ptr noalias %ptr2) { auto *S1 = cast(&*It++); auto *S0 = cast(&*It++); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({S0, S1})); EXPECT_TRUE(Sched.trySchedule({Add0, Add1})); EXPECT_TRUE(Sched.trySchedule({L0, L1})); @@ -570,7 +578,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, ptr noalias %ptr2) { auto *S1 = cast(&*It++); auto *S0 = cast(&*It++); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({S0, S1})); EXPECT_TRUE(Sched.trySchedule({Add0, Add1})); EXPECT_TRUE(Sched.trySchedule({L0, L1})); @@ -609,7 +618,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, ptr noalias %ptr2) { auto *S1 = cast(&*It++); auto *S0 = cast(&*It++); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); auto &DAG = sandboxir::SchedulerInternalsAttorney::getDAG(Sched); auto GetBndlSchedState = [&Sched](ArrayRef Instrs) { return sandboxir::SchedulerInternalsAttorney::getBndlSchedState(Sched, @@ -729,7 +739,8 @@ define void @foo(ptr noalias %ptrA0, ptr noalias %ptrA1, auto *Ret = cast(&*It++); (void)Ret; - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({A0, A1})); // NOTE: We schedule the intermediate nodes between {A0,A1} and {B0,B1} by // hand one by one to make sure they are scheduled in that order because @@ -781,7 +792,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, i8 %v0, i8 %v1) { { // Schedule bottom-up - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({Ret})); EXPECT_TRUE(Sched.trySchedule({S0, S1})); // Scheduling across blocks should fail. @@ -789,7 +801,8 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, i8 %v0, i8 %v1) { } { // Schedule top-down - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); EXPECT_TRUE(Sched.trySchedule({Add0, Add1})); // Scheduling across blocks should fail. EXPECT_FALSE(Sched.trySchedule({S0, S1})); @@ -815,7 +828,8 @@ define void @foo(ptr noalias %ptr, ptr noalias %ptr1, ptr noalias %ptr2) { auto *Ptr1 = F->getArg(1); auto *Ptr2 = F->getArg(2); - sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx); + sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx, + sandboxir::SchedDirection::BottomUp); // Schedule Ret and S0. The top of schedule should be at S0. EXPECT_TRUE(Sched.trySchedule({Ret})); EXPECT_TRUE(Sched.trySchedule({S0})); diff --git a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp index 64101278c08bf..ebf7a0942ae2c 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "../lib/Transforms/Vectorize/VPlanVerifier.h" +#include "../lib/Transforms/Vectorize/LoopVectorizationPlanner.h" #include "../lib/Transforms/Vectorize/VPlan.h" -#include "../lib/Transforms/Vectorize/VPlanCFG.h" #include "VPlanTestBase.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -330,6 +330,34 @@ TEST_F(VPVerifierTest, NonHeaderPHIInHeader) { delete PHINode; } +TEST_F(VPVerifierTest, DerivedIVWithStartInLoopRegions) { + VPlan &Plan = getPlan(); + auto *I32Ty = Type::getInt32Ty(C); + VPBasicBlock *Entry = Plan.getEntry(); + VPBasicBlock *Latch = Plan.createVPBasicBlock("latch"); + + VPBuilder Builder(Latch); + VPValue *Start = Builder.createNot(Plan.getPoison(I32Ty)); + Builder.createDerivedIV(InductionDescriptor::IK_IntInduction, nullptr, Start, + Plan.getPoison(I32Ty), Plan.getPoison(I32Ty)); + Builder.createNaryOp(VPInstruction::BranchOnCond, Plan.getTrue()); + + VPRegionBlock *LoopR = Plan.createLoopRegion(I32Ty, DebugLoc::getUnknown(), + "loop", Latch, Latch); + VPBlockUtils::connectBlocks(Entry, LoopR); + VPBlockUtils::connectBlocks(LoopR, Plan.getScalarHeader()); + +#if GTEST_HAS_STREAM_REDIRECTION + ::testing::internal::CaptureStderr(); +#endif + EXPECT_FALSE(verifyVPlanIsValid(Plan)); +#if GTEST_HAS_STREAM_REDIRECTION + EXPECT_STREQ( + "VPDerivedIVRecipe must have start value defined outside loop regions\n", + ::testing::internal::GetCapturedStderr().c_str()); +#endif +} + TEST_F(VPVerifierTest, testRUN_VPLAN_PASS) { VPlan &Plan = getPlan(); VPIRValue *Zero = Plan.getConstantInt(32, 0); diff --git a/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn b/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn index 1fd0bcc1f6cb9..a6a8b2e812cff 100644 --- a/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn @@ -197,6 +197,10 @@ clang_tablegen("BuiltinsX86_64") { args = [ "-gen-clang-builtins" ] } +clang_tablegen("BuiltinsZOS") { + args = [ "-gen-clang-builtins" ] +} + clang_tablegen("BuiltinTemplates") { args = [ "-gen-clang-builtin-templates" ] } diff --git a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn index 181b2a2b4b2c1..814ee696396ac 100644 --- a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn @@ -39,6 +39,7 @@ static_library("Basic") { "//clang/include/clang/Basic:BuiltinsSystemZ", "//clang/include/clang/Basic:BuiltinsX86", "//clang/include/clang/Basic:BuiltinsX86_64", + "//clang/include/clang/Basic:BuiltinsZOS", "//clang/include/clang/Basic:DiagnosticGroups", "//clang/include/clang/Basic:DiagnosticStableIDs", "//clang/include/clang/Basic:RegularKeywordAttrInfo", diff --git a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn index f3ec70354a3f8..b9e755973053b 100644 --- a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn @@ -402,6 +402,7 @@ copy("Headers") { "zos_wrappers/locale.h", "zos_wrappers/math.h", "zos_wrappers/poll.h", + "zos_wrappers/stdlib.h", "zos_wrappers/string.h", "zos_wrappers/time.h", "zos_wrappers/variant.h", diff --git a/llvm/utils/gn/secondary/clang/lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn index cf00808a282fc..c68ea997b84ca 100644 --- a/llvm/utils/gn/secondary/clang/lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn @@ -9,6 +9,7 @@ static_library("SourceTransformation") { "//llvm/lib/Support", ] sources = [ + "SARIFTransformationReportFormat.cpp", "TransformationRegistry.cpp", "YAMLSourceEditFormat.cpp", ] diff --git a/llvm/utils/gn/secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn b/llvm/utils/gn/secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn index 9ed4ba1caea63..be0ba3213fe19 100644 --- a/llvm/utils/gn/secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn @@ -48,6 +48,7 @@ unittest("ClangScalableAnalysisTests") { "Serialization/JSONFormatTest/TUSummaryTest.cpp", "SourceTransformation/EmitterTest.cpp", "SourceTransformation/RegistryTest.cpp", + "SourceTransformation/SARIFFormatTest.cpp", "SourceTransformation/YAMLFormatTest.cpp", "SummaryData/SummaryDataTest.cpp", "SummaryNameTest.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn index 41f777a3c6d07..9e80699d585f8 100644 --- a/llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn @@ -10,6 +10,7 @@ static_library("ABI") { "IRTypeMapper.cpp", "TargetInfo.cpp", "Targets/BPF.cpp", + "Targets/X86.cpp", "Types.cpp", ] } diff --git a/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn index 45553cd03162e..a8891dee19ffa 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn @@ -6,6 +6,7 @@ unittest("DemangleTests") { "DLangDemangleTest.cpp", "DemangleTest.cpp", "ItaniumDemangleTest.cpp", + "MicrosoftDemangleTest.cpp", "OutputBufferTest.cpp", "PartialDemangleTest.cpp", "RustDemangleTest.cpp", diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td index 1b776519b1428..d42c74e963769 100644 --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td @@ -404,7 +404,7 @@ def EmitC_CastOp : EmitC_Op<"cast", bool hasSideEffects() { // Use the "pure" attribute to see whether this CastOp has side effects. // Note that by default, `pure` is not set. - return getPure(); + return !getPure(); } }]; } diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td index a42bb7a66aae7..fa44fe7a49158 100644 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td @@ -141,6 +141,28 @@ def OutlineRematerializationOpInterface : OpInterface<"OutlineRematerializationO }]; } +def OutlineIdentityOperandOpInterface + : OpInterface<"OutlineIdentityOperandOpInterface"> { + let cppNamespace = "::mlir::acc"; + + let description = [{ + An interface for operations with an "identity" operand (e.g. FIR's + dummy scope handle) that must never be duplicated, unlike operands + handled by `OutlineRematerializationOpInterface`. When such an + operation is sunk/cloned into an offload region and the operand would + otherwise reference a value outside it, drop the operand instead of + cloning it; implementations must preserve correctness some other way + (e.g. FIR's dominance-based scope lookup fallback). + }]; + + let methods = [ + InterfaceMethod<"Drop any identity operands from this operation " + "instance that reference values defined outside its " + "containing region.", + "void", "dropOutlinedIdentityOperands", (ins), [{}]>, + ]; +} + def OffloadRegionOpInterface : OpInterface<"OffloadRegionOpInterface"> { let cppNamespace = "::mlir::acc"; diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td index 5e5760e33b5f6..e3b74f5a07d3f 100644 --- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td +++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td @@ -2485,6 +2485,7 @@ def Tosa_TileOp : Tosa_InferShapedTypeOp<"tile", [Pure]> { LogicalResult getConstantMultiples(llvm::SmallVector &multiples); }]; + let hasCanonicalizer = 1; let hasFolder = 1; let hasVerifier = 1; diff --git a/mlir/include/mlir/Dialect/XeGPU/Transforms/XeGPULayoutImpl.h b/mlir/include/mlir/Dialect/XeGPU/Transforms/XeGPULayoutImpl.h index 5f313e480c918..75fcb156a9d0d 100644 --- a/mlir/include/mlir/Dialect/XeGPU/Transforms/XeGPULayoutImpl.h +++ b/mlir/include/mlir/Dialect/XeGPU/Transforms/XeGPULayoutImpl.h @@ -234,15 +234,19 @@ DistributeLayoutAttr setupLoadMatrixAnchorLayout( DistributeLayoutAttr consumerLayout, const uArch::uArch *uArch); /// Sets up the anchor layout for a store scatter operation. +/// `numSg` is only used for Subgroup-kind layouts. DistributeLayoutAttr setupStoreScatterAnchorLayout(LayoutKind layoutKind, VectorType vectorTy, int contigChunkSize, + int numSg, const uArch::uArch *uArch); /// Sets up the anchor layout for a store matrix operation. +/// `numSg` is only used for Subgroup-kind layouts. DistributeLayoutAttr setupStoreMatrixAnchorLayout(LayoutKind layoutKind, VectorType vectorTy, int contigChunkSize, + int numSg, const uArch::uArch *uArch); /// If the consumer layout has only inst_data (no lane_layout/lane_data), diff --git a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp index 8b113478be71d..0822c44c10f1d 100644 --- a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp +++ b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp @@ -2035,6 +2035,8 @@ void mlir::populateSPIRVToLLVMConversionPatterns( ClampPattern, DirectConversionPattern, DirectConversionPattern, + DirectConversionPattern, + DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, @@ -2083,6 +2085,8 @@ void mlir::populateSPIRVToLLVMConversionPatterns( DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, + DirectConversionPattern, + DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, diff --git a/mlir/lib/Conversion/VectorToXeGPU/VectorToXeGPU.cpp b/mlir/lib/Conversion/VectorToXeGPU/VectorToXeGPU.cpp index 8dcc9771d8db4..dd7330e4ea950 100644 --- a/mlir/lib/Conversion/VectorToXeGPU/VectorToXeGPU.cpp +++ b/mlir/lib/Conversion/VectorToXeGPU/VectorToXeGPU.cpp @@ -97,6 +97,8 @@ static LogicalResult transferPreconditions(PatternRewriter &rewriter, VectorType vecTy = xferOp.getVectorType(); unsigned vecRank = vecTy.getRank(); + if (vecRank == 0) + return rewriter.notifyMatchFailure(xferOp, "0D vectors are not supported"); if (xferOp.hasOutOfBoundsDim() && vecRank < 2) return rewriter.notifyMatchFailure( xferOp, "Boundary check is available only for block instructions."); diff --git a/mlir/lib/Dialect/OpenACC/Transforms/OffloadLiveInValueCanonicalization.cpp b/mlir/lib/Dialect/OpenACC/Transforms/OffloadLiveInValueCanonicalization.cpp index 60285c8a02bb9..4b57354b8b5d8 100644 --- a/mlir/lib/Dialect/OpenACC/Transforms/OffloadLiveInValueCanonicalization.cpp +++ b/mlir/lib/Dialect/OpenACC/Transforms/OffloadLiveInValueCanonicalization.cpp @@ -246,6 +246,13 @@ class OffloadLiveInValueCanonicalization Operation *sinkOp = sinkCandidate.getDefiningOp(); assert(sinkOp && "must have op to be considered"); sinkOp->moveBefore(®ion.front().front()); + // Some operations (e.g. fir.declare) may carry identity operands that + // must not be left referencing a value defined outside the region. + // Unlike other operands, such identity operands cannot simply be + // treated as new live-ins to legalize; they must be dropped instead. + if (auto identityOp = + dyn_cast(sinkOp)) + identityOp.dropOutlinedIdentityOperands(); LLVM_DEBUG(llvm::dbgs() << "\t\tSunk: " << *sinkOp << "\n"); } @@ -262,6 +269,14 @@ class OffloadLiveInValueCanonicalization computeTopologicalSorting(opsToRematerialize); for (Operation *rematerializationOp : opsToRematerialize) { Operation *clonedOp = builder.clone(*rematerializationOp); + // See the comment above: identity operands must be dropped from the + // clone rather than duplicated, since duplicating them would make the + // clone appear to belong to a different instantiation than the + // original operation (and any of its siblings left outside the + // region). + if (auto identityOp = + dyn_cast(clonedOp)) + identityOp.dropOutlinedIdentityOperands(); for (auto [oldResult, newResult] : llvm::zip( rematerializationOp->getResults(), clonedOp->getResults())) { replaceAllUsesInRegionWith(oldResult, newResult, region); diff --git a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp index 4c98aca0ee8d7..19f35757bdd83 100644 --- a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp +++ b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp @@ -20,8 +20,10 @@ #include "mlir/Dialect/Traits.h" #include "mlir/IR/BuiltinTypeInterfaces.h" #include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/IRMapping.h" #include "mlir/IR/Matchers.h" #include "mlir/IR/PatternMatch.h" +#include "mlir/IR/TypeUtilities.h" #include "mlir/Transforms/FoldUtils.h" #include "mlir/Transforms/InliningUtils.h" #include "llvm/ADT/APFloat.h" @@ -2326,6 +2328,82 @@ OpFoldResult tosa::SelectOp::fold(FoldAdaptor adaptor) { return {}; } +static LogicalResult verifyTileIsBroadcast(tosa::TileOp tileOp) { + const auto inputType = + dyn_cast(tileOp.getInput1().getType()); + const auto outputType = dyn_cast(tileOp.getType()); + if (!inputType || !outputType) + return failure(); + + SmallVector multiples; + if (failed(tileOp.getConstantMultiples(multiples))) + return failure(); + + for (const auto [index, multiple] : llvm::enumerate(multiples)) { + if (multiple == 1) + continue; + if (outputType.isDynamicDim(index)) + return failure(); + if (inputType.getDimSize(index) != 1) + return failure(); + } + + return success(); +} + +struct RemoveBroadcastTileFromBinaryElementwise + : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(tosa::TileOp tileOp, + PatternRewriter &rewriter) const override { + Value tileOutput = tileOp.getOutput(); + if (!tileOutput.hasOneUse()) + return rewriter.notifyMatchFailure(tileOp, + "tile output must have one use"); + + Operation *user = *tileOutput.user_begin(); + const bool isBinaryElementwise = + user->getNumOperands() == 2 && + user->hasTrait(); + if (!isBinaryElementwise && !isa(user)) + return rewriter.notifyMatchFailure( + tileOp, "consumer must be binary broadcastable"); + + if (failed(verifyTileIsBroadcast(tileOp))) + return rewriter.notifyMatchFailure( + tileOp, "tile must only expand statically-known singleton dims"); + + Value lhsOperand = user->getOperand(0); + Value rhsOperand = user->getOperand(1); + Value otherOperand = lhsOperand == tileOutput ? rhsOperand : lhsOperand; + Value tileInput = tileOp.getInput1(); + + const ShapedType newOtherType = cast(otherOperand.getType()); + const ShapedType newTileType = cast(tileInput.getType()); + SmallVector broadcastedShape; + OpTrait::util::getBroadcastedShape( + newOtherType.getShape(), newTileType.getShape(), broadcastedShape); + + const ShapedType outputType = cast(user->getResultTypes()[0]); + if (!llvm::equal(broadcastedShape, outputType.getShape())) + return rewriter.notifyMatchFailure( + tileOp, "tile output must be broadcastable to consumer operands"); + + rewriter.setInsertionPoint(user); + IRMapping mapper; + mapper.map(tileOutput, tileOp.getInput1()); + Operation *newUser = rewriter.clone(*user, mapper); + rewriter.replaceOp(user, newUser->getResults()); + return success(); + } +}; + +void TileOp::getCanonicalizationPatterns(RewritePatternSet &results, + MLIRContext *context) { + results.add(context); +} + OpFoldResult TileOp::fold(FoldAdaptor adaptor) { if (getInput1().getType() == getType()) { if (auto multiples = llvm::dyn_cast_if_present( diff --git a/mlir/lib/Dialect/Tosa/Transforms/TosaReduceTransposes.cpp b/mlir/lib/Dialect/Tosa/Transforms/TosaReduceTransposes.cpp index 0bd415040f22f..ffd48e8ab16ae 100644 --- a/mlir/lib/Dialect/Tosa/Transforms/TosaReduceTransposes.cpp +++ b/mlir/lib/Dialect/Tosa/Transforms/TosaReduceTransposes.cpp @@ -233,8 +233,7 @@ TosaReduceTransposes::transposeDenseAttribute(DenseElementsAttr input, // perms: dim 0→2, dim 1→0, dim 2→1, giving source position // calculated as 1*inputStrides[2] + 1*inputStrides[0] + 2*inputStrides[1] // = 1*1 + 1*12 + 2*4 = 21 - - size_t elementSize = oldType.getElementTypeBitWidth() / 8; + size_t elementSize = llvm::divideCeil(oldType.getElementTypeBitWidth(), 8); int64_t numElements = oldType.getNumElements(); SmallVector outputBuffer(numElements * elementSize); diff --git a/mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp b/mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp index f9c258aba5bc7..0951350e2fe82 100644 --- a/mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp +++ b/mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp @@ -704,40 +704,23 @@ DistributeLayoutAttr LayoutAttr::collapseDims(SmallVector dimGroup) { // Derive a new layout by expanding a single dimension `dim` into multiple // adjacent dimensions whose extents are given by `targetShape`. // -// Distribution is always outer-to-inner to make sure larger contiguous -// chunks are given to each compute unit first. Concretely: sg_layout and -// lane_layout walk the new dims outer-to-inner so each compute unit owns a -// contiguous run after collapse; sg_data / lane_data / inst_data fill -// innermost-first so the per-unit data tile is contiguous in the -// fastest-varying expanded dim. The expanded dims are assumed to be in -// row-major (FCD-first) order, which is intrinsic to `vector.shape_cast`'s -// linear-order-preserving semantics. -// -// Distribution policy on the expanded src dims (replacing `dim`): -// - sg_layout / lane_layout: spread outer-to-inner; each dim takes -// min(remaining, targetShape[i]); leftover spills into the next inner -// dim. -// - sg_data: fill innermost-first, capped per dim by -// targetShape[i] / sgLayout[i] (the per-sg share of the extent), -// or targetShape[i] (if sg_data is replicated across all subgroups). -// - lane_data: fill innermost-first, capped per dim by -// (targetShape[i] / sgLayout[i]) / laneLayout[i] (the per-lane share of -// the per-sg extent). -// - inst_data: seeded from laneLayout[i] * laneData[i] per dim, then the -// remaining factor is distributed innermost-first (capped per dim by -// the per-sg extent). -// - order: the original dim index is replaced by the expanded dim indices -// in innermost-fastest order; entries past `dim` shift up by -// `targetShape.size() - 1`. +// The expanded dims are row-major (innermost is fastest-varying), so every +// field is spread innermost-first. For sg and lane levels the data component +// (sg_data / lane_data) is distributed first and the layout component +// (sg_layout / lane_layout) then strides over the per-dim leftover; this +// shared inner-first sweep is what makes "wrap-around" distributions correct. +// When the data component spans the full extent (replicated/broadcast across +// subgroups or lanes), the layout component is capped by the full extent +// instead of the leftover. order entries past `dim` shift up by +// `targetShape.size() - 1`. // // Examples (only the affected dim shown; assume rank-1 input): -// layout, expandDim(0, [8, 16, 32]) -// -> sg_layout=[8, 1, 1], sg_data=[1, 16, 32] -// layout, expandDim(0, [2, 8, 32]) -// -> sg_layout=[2, 8, 1], sg_data=[1, 1, 32] (sg_layout spills inward) -// layout, -// expandDim(0, [8, 16, 32]) -// -> inst_data=[8, 2, 2], lane_layout=[8, 2, 1], lane_data=[1, 1, 1] +// sg_layout=[8], sg_data=[512], expandDim(0, [8,16,32]) +// -> sg_layout=[8,1,1], sg_data=[1,16,32] +// sg_layout=[4], sg_data=[4], expandDim(0, [2,16]) +// -> sg_layout=[1,4], sg_data=[1,4] (wrap-around) +// inst_data=[32], lane_layout=[16], lane_data=[1], expandDim(0, [8,16,32]) +// -> inst_data=[1,1,32], lane_layout=[1,1,16], lane_data=[1,1,1] DistributeLayoutAttr LayoutAttr::expandDim(int64_t dim, ArrayRef targetShape) { SmallVector sgLayout = getEffectiveSgLayoutAsInt(); @@ -761,29 +744,22 @@ DistributeLayoutAttr LayoutAttr::expandDim(int64_t dim, int64_t origLaneDataDim = laneData.empty() ? 1 : laneData[dim]; int64_t origInstDataDim = instData.empty() ? 1 : instData[dim]; - // Spread `total` across the new dims (length expCount), capped per dim by - // `dimSizeCap[i]`. `outerToInner` selects iteration direction - // (true = i=0..n-1). - auto spread = [&](int64_t total, ArrayRef dimSizeCap, - bool outerToInner) -> SmallVector { + // Spread `total` across the new dims (length expCount), innermost-first, + // capped per dim by `dimSizeCap[i]`. + auto spread = [&](int64_t total, + ArrayRef dimSizeCap) -> SmallVector { SmallVector out(expCount, 1); int64_t remaining = total; - auto step = [&](int64_t i) { + for (int64_t i = expCount - 1; i >= 0; --i) { if (remaining == 1) - return; + break; int64_t take = std::min(remaining, dimSizeCap[i]); assert(take > 0 && "expandDim distribution must not be zero"); assert(remaining % take == 0 && "expandDims must divide evenly across dims"); out[i] = take; remaining /= take; - }; - if (outerToInner) - for (int64_t i = 0; i < expCount; ++i) - step(i); - else - for (int64_t i = expCount - 1; i >= 0; --i) - step(i); + } assert(remaining == 1 && "expandDims total must fit within target shape"); return out; }; @@ -803,60 +779,61 @@ DistributeLayoutAttr LayoutAttr::expandDim(int64_t dim, bool hasLaneData = !laneData.empty(); bool hasInstData = !instData.empty(); - // sg_layout / sg_data - SmallVector expSgLayout(expCount, 1); - if (hasSgLayout) { - expSgLayout = spread(origSgLayoutDim, targetShape, /*outerToInner=*/true); - splice(sgLayout, expSgLayout); - } + // sg_data first, then sg_layout into the per-dim leftover. When sg_data is + // replicated across subgroups it spans the full extent, so sg_layout is + // capped by targetShape itself instead of the leftover. bool sgDataReplicated = hasSgData && origSgDataDim == computeProduct(targetShape); + SmallVector expSgData(expCount, 1); if (hasSgData) { + expSgData = spread(origSgDataDim, targetShape); + splice(sgData, expSgData); + } + SmallVector expSgLayout(expCount, 1); + if (hasSgLayout) { SmallVector dimSizeCap(targetShape.begin(), targetShape.end()); - if (hasSgLayout && !sgDataReplicated) + if (hasSgData && !sgDataReplicated) for (int64_t i = 0; i < expCount; ++i) - dimSizeCap[i] /= expSgLayout[i]; - SmallVector expSgData = - spread(origSgDataDim, dimSizeCap, /*outerToInner=*/false); - splice(sgData, expSgData); + dimSizeCap[i] /= expSgData[i]; + expSgLayout = spread(origSgLayoutDim, dimSizeCap); + splice(sgLayout, expSgLayout); } - // Per-sg view used as the base for lane_layout / lane_data / inst_data: - // targetShape[i] / sg_layout[i] when sg_layout is present (and not - // replicated), else targetShape itself. + // Per-sg extent feeding lane_layout / lane_data / inst_data. SmallVector perSgShape(targetShape.begin(), targetShape.end()); if (hasSgLayout && !sgDataReplicated) for (int64_t i = 0; i < expCount; ++i) perSgShape[i] /= expSgLayout[i]; - // lane_layout / lane_data + // lane_data first, then lane_layout into the per-dim leftover. When lane_data + // is replicated across lanes it spans the full per-sg extent, so lane_layout + // is capped by perSgShape itself instead of the leftover. + bool laneDataReplicated = + hasLaneData && origLaneDataDim == computeProduct(perSgShape); SmallVector expLaneLayout(expCount, 1); SmallVector expLaneData(expCount, 1); + if (hasLaneData) + expLaneData = spread(origLaneDataDim, perSgShape); if (hasLaneLayout) { - expLaneLayout = spread(origLaneLayoutDim, perSgShape, - /*outerToInner=*/true); - splice(laneLayout, expLaneLayout); - } - if (hasLaneData) { SmallVector dimSizeCap(perSgShape.begin(), perSgShape.end()); - if (hasLaneLayout) + if (hasLaneData && !laneDataReplicated) for (int64_t i = 0; i < expCount; ++i) - dimSizeCap[i] /= expLaneLayout[i]; - expLaneData = spread(origLaneDataDim, dimSizeCap, /*outerToInner=*/false); - splice(laneData, expLaneData); + dimSizeCap[i] /= expLaneData[i]; + expLaneLayout = spread(origLaneLayoutDim, dimSizeCap); } + if (hasLaneData) + splice(laneData, expLaneData); + if (hasLaneLayout) + splice(laneLayout, expLaneLayout); - // inst_data: when lane info is present, the per-lane atom - // `laneLayout[i] * laneData[i]` is the minimum granularity each new dim must - // hold to keep the lane-level distribution unit aligned with inst_data; the - // remaining factor `inst_data / laneAtom` is then spread innermost-first - // (capped by `perSgShape[i] / atom[i]`) and multiplied back onto the atom. - // Without lane info, fall back to a plain innermost-first spread over - // perSgShape. + // inst_data: seed each dim from the per-lane atom + // `laneLayout[i]*laneData[i]`, spread the remaining factor over the leftover, + // then scale back by the atom. Without lane info, spread inst_data directly + // over the per-sg extent. if (hasInstData) { SmallVector expInstData; if (!hasLaneLayout || !hasLaneData) { - expInstData = spread(origInstDataDim, perSgShape, /*outerToInner=*/false); + expInstData = spread(origInstDataDim, perSgShape); } else { int64_t laneAtom = origLaneLayoutDim * origLaneDataDim; SmallVector atom(expCount, 1); @@ -865,8 +842,7 @@ DistributeLayoutAttr LayoutAttr::expandDim(int64_t dim, atom[i] = expLaneLayout[i] * expLaneData[i]; dimSizeCap[i] = perSgShape[i] / atom[i]; } - expInstData = spread(origInstDataDim / laneAtom, dimSizeCap, - /*outerToInner=*/false); + expInstData = spread(origInstDataDim / laneAtom, dimSizeCap); for (int64_t i = 0; i < expCount; ++i) expInstData[i] *= atom[i]; } diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPULayoutImpl.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPULayoutImpl.cpp index 6ea55f4c78dd6..8da151a333fb3 100644 --- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPULayoutImpl.cpp +++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPULayoutImpl.cpp @@ -1752,31 +1752,39 @@ xegpu::setupLoadMatrixAnchorLayout(xegpu::LayoutKind layoutKind, maxChunkSize, resShape, subgroupSize); } -/// Sets up the anchor layout for store scatter and store matrix operation. -/// store matrix lowers to store scatter and 1d block store. All of them -/// share the same layout setup logic. For Subgroup layout, not supported -/// yet. -/// -/// Lane layout is derived first via `computeScatterIOLaneLayoutAndData`; -/// inst_data is then the element-wise product lane_layout * lane_data. +/// Picks the subgroup layout for a scatter-style store (store_scatter / +/// store_matrix): the most balanced `numSg` factorization that divides +/// `wgShape` with sg_data a multiple of `instData`. A store has no consumer. static xegpu::DistributeLayoutAttr -setupGenericStoreAnchorLayout(xegpu::LayoutKind layoutKind, - mlir::MLIRContext *context, int maxChunkSize, - ArrayRef srcShape, int subgroupSize) { - - if (layoutKind == xegpu::LayoutKind::Subgroup) { - assert(false && - "subgroup layout assignment not supported for storeScatter."); +getStoreSubgroupLayouts(mlir::MLIRContext *context, ArrayRef wgShape, + ArrayRef instData, int numSg) { + auto candidates = getSgLayoutCandidates(wgShape, instData, numSg); + if (candidates.empty()) return nullptr; - } + // Candidates are ordered most-balanced first. + return buildSgLayout(context, wgShape, candidates.front(), /*dimK=*/-1); +} + +/// Sets up the anchor layout for store scatter and store matrix operation, +/// which share the same logic. Lane layout comes from +/// `computeScatterIOLaneLayoutAndData`; inst_data is lane_layout * lane_data. +static xegpu::DistributeLayoutAttr setupGenericStoreAnchorLayout( + xegpu::LayoutKind layoutKind, mlir::MLIRContext *context, int maxChunkSize, + ArrayRef srcShape, int subgroupSize, int numSg) { auto [laneLayout, laneData] = computeScatterIOLaneLayoutAndData(srcShape, subgroupSize, maxChunkSize); + SmallVector instData(srcShape.size()); + for (size_t i = 0; i < srcShape.size(); ++i) + instData[i] = laneLayout[i] * laneData[i]; + + if (layoutKind == xegpu::LayoutKind::Subgroup) { + assert(numSg > 0 && + "Number of subgroups must be provided for sg layout creation."); + return getStoreSubgroupLayouts(context, srcShape, instData, numSg); + } if (layoutKind == xegpu::LayoutKind::InstData) { - SmallVector instData(srcShape.size()); - for (size_t i = 0; i < srcShape.size(); ++i) - instData[i] = laneLayout[i] * laneData[i]; return buildInstDataLayoutWithLane(context, instData, laneLayout, laneData); } if (layoutKind == xegpu::LayoutKind::Lane) { @@ -1789,7 +1797,7 @@ setupGenericStoreAnchorLayout(xegpu::LayoutKind layoutKind, xegpu::DistributeLayoutAttr xegpu::setupStoreScatterAnchorLayout(xegpu::LayoutKind layoutKind, VectorType srcVecTy, int contigChunkSize, - const uArch::uArch *uArch) { + int numSg, const uArch::uArch *uArch) { const int subgroupSize = uArch->getSubgroupSize(); ArrayRef srcShape = srcVecTy.getShape(); @@ -1801,14 +1809,13 @@ xegpu::setupStoreScatterAnchorLayout(xegpu::LayoutKind layoutKind, int maxChunkSize = std::min(uArchInstruction->getMaxLaneAccessSizeBytes(), contigChunkSize); return setupGenericStoreAnchorLayout(layoutKind, context, maxChunkSize, - srcShape, subgroupSize); + srcShape, subgroupSize, numSg); } /// Sets up the anchor layout for a store matrix operation. -xegpu::DistributeLayoutAttr -xegpu::setupStoreMatrixAnchorLayout(xegpu::LayoutKind layoutKind, - VectorType srcVecTy, int contigChunkSize, - const xegpu::uArch::uArch *uArch) { +xegpu::DistributeLayoutAttr xegpu::setupStoreMatrixAnchorLayout( + xegpu::LayoutKind layoutKind, VectorType srcVecTy, int contigChunkSize, + int numSg, const xegpu::uArch::uArch *uArch) { const int subgroupSize = uArch->getSubgroupSize(); ArrayRef srcShape = srcVecTy.getShape(); @@ -1821,7 +1828,7 @@ xegpu::setupStoreMatrixAnchorLayout(xegpu::LayoutKind layoutKind, std::min(uArchInstruction->getMaxLaneAccessSizeBytes(), contigChunkSize); return setupGenericStoreAnchorLayout(layoutKind, context, maxChunkSize, - srcShape, subgroupSize); + srcShape, subgroupSize, numSg); } /// Completes a scatter IO layout by deriving lane_layout and lane_data from diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp index 64d0d8063b7ff..1b1abcc4b0e4f 100644 --- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp +++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp @@ -1273,8 +1273,19 @@ void LayoutInfoPropagation::visitStoreScatterOp( storeScatter.emitWarning("Not propagating, non-vector payload supplied."); return; } + auto numSgOrErr = getNumSg(storeScatter, uArch->getSubgroupSize()); + if (layoutKind == xegpu::LayoutKind::Subgroup && failed(numSgOrErr)) { + storeScatter.emitWarning( + "Unable to determine the number of subgroups for the operation."); + return; + } requiredAnchorLayoutAttr = xegpu::setupStoreScatterAnchorLayout( - layoutKind, srcVecTy, chunkSize, uArch); + layoutKind, srcVecTy, chunkSize, numSgOrErr.value_or(0), uArch); + if (!requiredAnchorLayoutAttr) { + storeScatter.emitWarning( + "Failed to determine required layout for store scatter."); + return; + } storeScatter.setLayoutAttr(requiredAnchorLayoutAttr); } @@ -1357,8 +1368,19 @@ void LayoutInfoPropagation::visitStoreMatrixOp( } else { int chunkSize = 1; // placeHolder for future use when StoreMatrix supports coalescing + auto numSgOrErr = getNumSg(storeMatrix, uArch->getSubgroupSize()); + if (layoutKind == xegpu::LayoutKind::Subgroup && failed(numSgOrErr)) { + storeMatrix.emitWarning( + "Unable to determine the number of subgroups for the operation."); + return; + } requiredAnchorLayoutAttr = xegpu::setupStoreMatrixAnchorLayout( - layoutKind, srcVecTy, chunkSize, uArch); + layoutKind, srcVecTy, chunkSize, numSgOrErr.value_or(0), uArch); + if (!requiredAnchorLayoutAttr) { + storeMatrix.emitWarning( + "Failed to determine required layout for store matrix."); + return; + } storeMatrix.setLayoutAttr(requiredAnchorLayoutAttr); } layout = LayoutInfo(requiredAnchorLayoutAttr); diff --git a/mlir/lib/Transforms/RemoveDeadValues.cpp b/mlir/lib/Transforms/RemoveDeadValues.cpp index f0a210a2ededb..6e55bc390be23 100644 --- a/mlir/lib/Transforms/RemoveDeadValues.cpp +++ b/mlir/lib/Transforms/RemoveDeadValues.cpp @@ -259,7 +259,7 @@ static void processSimpleOp(Operation *op, RunLivenessAnalysis &la, } /// Process a function-like operation `funcOp` using the liveness analysis `la` -/// and the IR in `module`. If it is not public or external: +/// and `symbolUserMap`. If it is not public or external: /// (1) Adding its non-live arguments to a list for future removal. /// (2) Marking their corresponding operands in its callers for removal. /// (3) Identifying and enqueueing unnecessary terminator operands @@ -268,7 +268,8 @@ static void processSimpleOp(Operation *op, RunLivenessAnalysis &la, /// (5) Collecting the uses of these return values in its callers for future /// removal. /// (6) Marking all its results as non-live values. -static void processFuncOp(FunctionOpInterface funcOp, Operation *module, +static void processFuncOp(FunctionOpInterface funcOp, + const SymbolUserMap &symbolUserMap, RunLivenessAnalysis &la, DenseSet &nonLiveSet, RDVFinalCleanupList &cl) { LDBG() << "Processing function op: " @@ -279,10 +280,8 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module, << funcOp.getOperation()->getName(); return; } - SymbolTable::UseRange uses = *funcOp.getSymbolUses(module); - if (llvm::any_of(uses, [](SymbolTable::SymbolUse use) { - return !isa(use.getUser()); - })) { + ArrayRef users = symbolUserMap.getUsers(funcOp); + if (!llvm::all_of(users, llvm::IsaPred)) { // If a non-call operation references the function (e.g. spirv.EntryPoint), // we cannot safely remove arguments or return values since we don't know // what the user expects. Skip this function entirely. @@ -301,8 +300,7 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module, // Do (2). (Skip creating generic operand cleanup entries for call ops. // Call arguments will be removed in the call-site specific segment-aware // cleanup, avoiding generic eraseOperands bitvector mechanics.) - for (SymbolTable::SymbolUse use : uses) { - Operation *callOp = use.getUser(); + for (Operation *callOp : users) { // Push an empty operand cleanup entry so that call-site specific logic in // cleanUpDeadVals runs (it keys off CallOpInterface). The BitVector is // intentionally all false to avoid generic erasure. @@ -336,8 +334,7 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module, // since it forwards only to non-live value(s) (%1#1). size_t numReturns = funcOp.getNumResults(); BitVector nonLiveRets(numReturns, true); - for (SymbolTable::SymbolUse use : uses) { - Operation *callOp = use.getUser(); + for (Operation *callOp : users) { assert(isa(callOp) && "expected a call-like user"); BitVector liveCallRets = markLives(callOp->getResults(), nonLiveSet, la); nonLiveRets &= liveCallRets.flip(); @@ -360,8 +357,7 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module, // Do (5) and (6). if (numReturns == 0) return; - for (SymbolTable::SymbolUse use : uses) { - Operation *callOp = use.getUser(); + for (Operation *callOp : users) { assert(isa(callOp) && "expected a call-like user"); cl.results.push_back({callOp, nonLiveRets}); collectNonLiveValues(nonLiveSet, callOp->getResults(), nonLiveRets); @@ -520,15 +516,12 @@ static void processBranchOp(BranchOpInterface branchOp, RunLivenessAnalysis &la, } } -/// Create ub.poison ops for the given values. If a value has no uses, return -/// an "empty" value. -static SmallVector createPoisonedValues(OpBuilder &b, - ValueRange values) { - return llvm::map_to_vector(values, [&](Value value) { - if (value.use_empty()) - return Value(); - return ub::PoisonOp::create(b, value.getLoc(), value.getType()).getResult(); - }); +/// Create a ub.poison op for the given value. If it has no uses, return an +/// "empty" value. +static Value createPoisonedValue(OpBuilder &b, Value value) { + if (value.use_empty()) + return Value(); + return ub::PoisonOp::create(b, value.getLoc(), value.getType()).getResult(); } namespace { @@ -558,7 +551,30 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { TrackingListener listener; IRRewriter rewriter(ctx, &listener); - // 1. Blocks, We must remove the block arguments and successor operands before + // 1. Operands to replace with poison. These rewrites need the original + // operand values for their location and type, so they must run before any + // cleanup that can drop uses and leave operands temporarily null. + LDBG() << "Replacing dead operands with poison in " << list.operands.size() + << " operand lists"; + for (OperandsToCleanup &o : list.operands) { + if (!o.replaceWithPoison || !o.nonLive.any()) + continue; + LDBG_OS([&](raw_ostream &os) { + os << "Replacing non-live operands ["; + llvm::interleaveComma(o.nonLive.set_bits(), os); + os << "] with poison in operation: " + << OpWithFlags(o.op, + OpPrintingFlags().skipRegions().printGenericOpForm()); + }); + rewriter.setInsertionPoint(o.op); + for (auto deadIdx : o.nonLive.set_bits()) { + Value operand = o.op->getOperand(deadIdx); + assert(operand && "expected non-null operand for poison replacement"); + o.op->setOperand(deadIdx, createPoisonedValue(rewriter, operand)); + } + } + + // 2. Blocks, We must remove the block arguments and successor operands before // deleting the operation, as they may reside in the region operation. LDBG() << "Cleaning up " << list.blocks.size() << " block argument lists"; for (auto &b : list.blocks) { @@ -583,7 +599,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { } } - // 2. Successor Operands + // 3. Successor Operands LDBG() << "Cleaning up " << list.successorOperands.size() << " successor operand lists"; for (auto &op : list.successorOperands) { @@ -607,7 +623,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { } } - // 3. Functions + // 4. Functions LDBG() << "Cleaning up " << list.functions.size() << " functions"; // Record which function arguments were erased so we can shrink call-site // argument segments for CallOpInterface operations (e.g. ops using @@ -641,9 +657,11 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { (void)f.funcOp.eraseResults(f.nonLiveRets); } - // 4. Operands + // 5. Operands LDBG() << "Cleaning up " << list.operands.size() << " operand lists"; for (OperandsToCleanup &o : list.operands) { + if (o.replaceWithPoison) + continue; // Handle call-specific cleanup only when we have a cached callee reference. // This avoids expensive symbol lookup and is defensive against future // changes. @@ -686,20 +704,11 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { << OpWithFlags(o.op, OpPrintingFlags().skipRegions().printGenericOpForm()); }); - if (o.replaceWithPoison) { - rewriter.setInsertionPoint(o.op); - for (auto deadIdx : o.nonLive.set_bits()) { - o.op->setOperand( - deadIdx, createPoisonedValues(rewriter, o.op->getOperand(deadIdx)) - .front()); - } - } else { - o.op->eraseOperands(o.nonLive); - } + o.op->eraseOperands(o.nonLive); } } - // 5. Results + // 6. Results LDBG() << "Cleaning up " << list.results.size() << " result lists"; for (auto &r : list.results) { LDBG_OS([&](raw_ostream &os) { @@ -712,7 +721,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { dropUsesAndEraseResults(rewriter, r.op, r.nonLive); } - // 6. Operations + // 7. Operations LDBG() << "Cleaning up " << list.operations.size() << " operations"; for (Operation *op : list.operations) { LDBG() << "Erasing operation: " @@ -741,7 +750,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { continue; rewriter.setInsertionPoint(op); - Value poisonedValue = createPoisonedValues(rewriter, opResult).front(); + Value poisonedValue = createPoisonedValue(rewriter, opResult); rewriter.replaceAllUsesWith(opResult, poisonedValue); } @@ -749,7 +758,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { rewriter.eraseOp(op); } - // 7. Remove all dead poison ops. + // 8. Remove all dead poison ops. for (ub::PoisonOp poisonOp : listener.poisonOps) { if (poisonOp.use_empty()) poisonOp.erase(); @@ -770,6 +779,13 @@ void RemoveDeadValues::runOnOperation() { auto &la = getAnalysis(); Operation *module = getOperation(); + // Build a symbol user map once up front so that processFuncOp can look up the + // callers of each function in O(1). Otherwise, each call would walk the + // entire module to find the callers, making the pass O(numFunctions * + // numOperations). + SymbolTableCollection symbolTableCollection; + SymbolUserMap symbolUserMap(symbolTableCollection, module); + // Tracks values eligible for erasure - complements liveness analysis to // identify "droppable" values. DenseSet deadVals; @@ -780,7 +796,7 @@ void RemoveDeadValues::runOnOperation() { module->walk([&](Operation *op) { if (auto funcOp = dyn_cast(op)) { - processFuncOp(funcOp, module, la, deadVals, finalCleanupList); + processFuncOp(funcOp, symbolUserMap, la, deadVals, finalCleanupList); } else if (auto regionBranchOp = dyn_cast(op)) { processRegionBranchOp(regionBranchOp, la, deadVals, finalCleanupList); } else if (auto branchOp = dyn_cast(op)) { diff --git a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir index a986be42a5437..e6fed930268d4 100644 --- a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir +++ b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir @@ -69,6 +69,10 @@ spirv.func @cl_binary_float(%arg0: f32, %arg1: f32) "None" { %2 = spirv.CL.fmax %arg0, %arg1 : f32 // CHECK: llvm.intr.minnum(%{{.*}}, %{{.*}}) : (f32, f32) -> f32 %3 = spirv.CL.fmin %arg0, %arg1 : f32 + // CHECK: llvm.intr.copysign(%{{.*}}, %{{.*}}) : (f32, f32) -> f32 + %4 = spirv.CL.copysign %arg0, %arg1 : f32 + // CHECK: llvm.frem %{{.*}}, %{{.*}} : f32 + %5 = spirv.CL.fmod %arg0, %arg1 : f32 spirv.Return } diff --git a/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir index 7be0bf201175f..08c7947861cb4 100644 --- a/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir +++ b/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir @@ -103,6 +103,32 @@ spirv.func @fclamp(%arg0: f32, %arg1: f32, %arg2: f32) "None" { spirv.Return } +//===----------------------------------------------------------------------===// +// spirv.GL.NMax +//===----------------------------------------------------------------------===// + +// CHECK-LABEL: @nmax +spirv.func @nmax(%arg0: f32, %arg1: vector<3xf16>) "None" { + // CHECK: llvm.intr.maxnum(%{{.*}}, %{{.*}}) : (f32, f32) -> f32 + %0 = spirv.GL.NMax %arg0, %arg0 : f32 + // CHECK: llvm.intr.maxnum(%{{.*}}, %{{.*}}) : (vector<3xf16>, vector<3xf16>) -> vector<3xf16> + %1 = spirv.GL.NMax %arg1, %arg1 : vector<3xf16> + spirv.Return +} + +//===----------------------------------------------------------------------===// +// spirv.GL.NMin +//===----------------------------------------------------------------------===// + +// CHECK-LABEL: @nmin +spirv.func @nmin(%arg0: f32, %arg1: vector<3xf16>) "None" { + // CHECK: llvm.intr.minnum(%{{.*}}, %{{.*}}) : (f32, f32) -> f32 + %0 = spirv.GL.NMin %arg0, %arg0 : f32 + // CHECK: llvm.intr.minnum(%{{.*}}, %{{.*}}) : (vector<3xf16>, vector<3xf16>) -> vector<3xf16> + %1 = spirv.GL.NMin %arg1, %arg1 : vector<3xf16> + spirv.Return +} + //===----------------------------------------------------------------------===// // spirv.GL.Log //===----------------------------------------------------------------------===// diff --git a/mlir/test/Conversion/VectorToXeGPU/transfer-read-to-xegpu.mlir b/mlir/test/Conversion/VectorToXeGPU/transfer-read-to-xegpu.mlir index f64bcc27940ea..6439e3a41e084 100644 --- a/mlir/test/Conversion/VectorToXeGPU/transfer-read-to-xegpu.mlir +++ b/mlir/test/Conversion/VectorToXeGPU/transfer-read-to-xegpu.mlir @@ -679,4 +679,22 @@ gpu.func @load_0D_memref_unsupported(%source: memref) -> vector { // CHECK-LABEL: @load_0D_memref_unsupported // CHECK: vector.transfer_read -} \ No newline at end of file +} + +// ----- +gpu.module @xevm_module { +gpu.func @load_0D_vector_unsupported(%source: memref<3xf32>, + %offset: index) -> vector { + %c0 = arith.constant 0.0 : f32 + %0 = vector.transfer_read %source[%offset], %c0 + : memref<3xf32>, vector + gpu.return %0 : vector +} + +// LOAD-ND-LABEL: @load_0D_vector_unsupported +// LOAD-ND: vector.transfer_read + +// LOAD-GATHER-LABEL: @load_0D_vector_unsupported +// LOAD-GATHER: vector.transfer_read + +} diff --git a/mlir/test/Conversion/VectorToXeGPU/transfer-write-to-xegpu.mlir b/mlir/test/Conversion/VectorToXeGPU/transfer-write-to-xegpu.mlir index a7cd3d7652d85..755b8a3abc4e0 100644 --- a/mlir/test/Conversion/VectorToXeGPU/transfer-write-to-xegpu.mlir +++ b/mlir/test/Conversion/VectorToXeGPU/transfer-write-to-xegpu.mlir @@ -412,3 +412,20 @@ gpu.func @store_1D_vector_addrspace3_unsupported(%vec: vector<8xf32>, // STORE-SCATTER: vector.transfer_write } + +// ----- +gpu.module @xevm_module { +gpu.func @store_0D_vector_unsupported(%vec: vector, + %source: memref<3xf32>, %offset: index) { + vector.transfer_write %vec, %source[%offset] + : vector, memref<3xf32> + gpu.return +} + +// STORE-ND-LABEL: @store_0D_vector_unsupported +// STORE-ND: vector.transfer_write + +// STORE-SCATTER-LABEL: @store_0D_vector_unsupported +// STORE-SCATTER: vector.transfer_write + +} diff --git a/mlir/test/Dialect/Tosa/canonicalize.mlir b/mlir/test/Dialect/Tosa/canonicalize.mlir index 6a3d84e8d133b..585589ac1405a 100644 --- a/mlir/test/Dialect/Tosa/canonicalize.mlir +++ b/mlir/test/Dialect/Tosa/canonicalize.mlir @@ -1996,6 +1996,166 @@ func.func @dont_canonicalize_non_const_avg_pool2d_adaptive(%arg0: tensor<1x?x?x8 // ----- +// CHECK-LABEL: @canonicalize_tile_broadcast_sub +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<96x56x56x96xf32>, %[[ARG1:[^:]+]]: tensor<1x56x56x1xf32> +// CHECK-NOT: tosa.tile +// CHECK: %[[SUB:.+]] = tosa.sub %[[ARG0]], %[[ARG1]] : (tensor<96x56x56x96xf32>, tensor<1x56x56x1xf32>) -> tensor<96x56x56x96xf32> +// CHECK: return %[[SUB]] +func.func @canonicalize_tile_broadcast_sub(%arg0: tensor<96x56x56x96xf32>, %arg1: tensor<1x56x56x1xf32>) -> tensor<96x56x56x96xf32> { + %shape = tosa.const_shape {values = dense<[96, 1, 1, 96]> : tensor<4xindex>} : () -> !tosa.shape<4> + %tile = tosa.tile %arg1, %shape : (tensor<1x56x56x1xf32>, !tosa.shape<4>) -> tensor<96x56x56x96xf32> + %sub = tosa.sub %arg0, %tile : (tensor<96x56x56x96xf32>, tensor<96x56x56x96xf32>) -> tensor<96x56x56x96xf32> + return %sub : tensor<96x56x56x96xf32> +} + +// ----- + +// CHECK-LABEL: @canonicalize_tile_broadcast_greater +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<1x197x768xf32>, %[[ARG1:[^:]+]]: tensor<1x197x1xf32> +// CHECK-NOT: tosa.tile +// CHECK: %[[GT:.+]] = tosa.greater %[[ARG0]], %[[ARG1]] : (tensor<1x197x768xf32>, tensor<1x197x1xf32>) -> tensor<1x197x768xi1> +// CHECK: return %[[GT]] +func.func @canonicalize_tile_broadcast_greater(%arg0: tensor<1x197x768xf32>, %arg1: tensor<1x197x1xf32>) -> tensor<1x197x768xi1> { + %shape = tosa.const_shape {values = dense<[1, 1, 768]> : tensor<3xindex>} : () -> !tosa.shape<3> + %tile = tosa.tile %arg1, %shape : (tensor<1x197x1xf32>, !tosa.shape<3>) -> tensor<1x197x768xf32> + %gt = tosa.greater %arg0, %tile : (tensor<1x197x768xf32>, tensor<1x197x768xf32>) -> tensor<1x197x768xi1> + return %gt : tensor<1x197x768xi1> +} + +// ----- + +// CHECK-LABEL: @canonicalize_tile_broadcast_mul +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<1x197x768xf32>, %[[ARG1:[^:]+]]: tensor<1x197x1xf32>, %[[SHIFT:[^:]+]]: tensor<1xi8> +// CHECK-NOT: tosa.tile +// CHECK: %[[MUL:.+]] = tosa.mul %[[ARG0]], %[[ARG1]], %[[SHIFT]] : (tensor<1x197x768xf32>, tensor<1x197x1xf32>, tensor<1xi8>) -> tensor<1x197x768xf32> +// CHECK: return %[[MUL]] +func.func @canonicalize_tile_broadcast_mul(%arg0: tensor<1x197x768xf32>, %arg1: tensor<1x197x1xf32>, %shift: tensor<1xi8>) -> tensor<1x197x768xf32> { + %shape = tosa.const_shape {values = dense<[1, 1, 768]> : tensor<3xindex>} : () -> !tosa.shape<3> + %tile = tosa.tile %arg1, %shape : (tensor<1x197x1xf32>, !tosa.shape<3>) -> tensor<1x197x768xf32> + %mul = tosa.mul %arg0, %tile, %shift : (tensor<1x197x768xf32>, tensor<1x197x768xf32>, tensor<1xi8>) -> tensor<1x197x768xf32> + return %mul : tensor<1x197x768xf32> +} + + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_when_result_no_longer_broadcastable +// CHECK: tosa.tile +// CHECK: tosa.sub +func.func @dont_canonicalize_tile_when_result_no_longer_broadcastable(%arg0: tensor<2x1xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %sub = tosa.sub %tile, %arg0 : (tensor<2x4xf32>, tensor<2x1xf32>) -> tensor<2x4xf32> + return %sub : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_second_tile_when_result_no_longer_broadcastable +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<2x1xf32> +// CHECK: %[[SHAPE:.+]] = tosa.const_shape +// CHECK: %[[TILE:.+]] = tosa.tile %[[ARG0]], %[[SHAPE]] +// CHECK: %[[ADD:.+]] = tosa.add %[[ARG0]], %[[TILE]] : (tensor<2x1xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> +// CHECK: return %[[ADD]] +func.func @dont_canonicalize_second_tile_when_result_no_longer_broadcastable(%arg0: tensor<2x1xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile0 = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %tile1 = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %add = tosa.add %tile0, %tile1 : (tensor<2x4xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> + return %add : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_with_unranked_other_operand +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<2x1xf32>, %[[ARG1:[^:]+]]: tensor<*xf32> +// CHECK: %[[SHAPE:.+]] = tosa.const_shape +// CHECK: %[[TILE:.+]] = tosa.tile %[[ARG0]], %[[SHAPE]] +// CHECK: %[[SUB:.+]] = tosa.sub %[[ARG1]], %[[TILE]] : (tensor<*xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> +// CHECK: return %[[SUB]] +func.func @dont_canonicalize_tile_with_unranked_other_operand(%arg0: tensor<2x1xf32>, %arg1: tensor<*xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %sub = tosa.sub %arg1, %tile : (tensor<*xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> + return %sub : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_non_singleton_expansion +// CHECK: tosa.tile +// CHECK: tosa.sub +func.func @dont_canonicalize_tile_non_singleton_expansion(%arg0: tensor<1x56x56x96xf32>, %arg1: tensor<1x56x56x2xf32>) -> tensor<1x56x56x96xf32> { + %shape = tosa.const_shape {values = dense<[1, 1, 1, 48]> : tensor<4xindex>} : () -> !tosa.shape<4> + %tile = tosa.tile %arg1, %shape : (tensor<1x56x56x2xf32>, !tosa.shape<4>) -> tensor<1x56x56x96xf32> + %sub = tosa.sub %arg0, %tile : (tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32>) -> tensor<1x56x56x96xf32> + return %sub : tensor<1x56x56x96xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_dynamic_expanded_dim +// CHECK: tosa.tile +// CHECK: tosa.sub +func.func @dont_canonicalize_tile_dynamic_expanded_dim(%arg0: tensor<2x?xf32>, %arg1: tensor<2x4xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg0, %shape : (tensor<2x?xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %sub = tosa.sub %arg1, %tile : (tensor<2x4xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> + return %sub : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_dynamic_output +// CHECK: tosa.tile +// CHECK: tosa.sub +func.func @dont_canonicalize_tile_dynamic_output(%arg0: tensor<2x?xf32>, %arg1: tensor<2x1xf32>) -> tensor<2x?xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg1, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x?xf32> + %sub = tosa.sub %arg0, %tile : (tensor<2x?xf32>, tensor<2x?xf32>) -> tensor<2x?xf32> + return %sub : tensor<2x?xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_multi_use +// CHECK: tosa.tile +// CHECK: tosa.sub +// CHECK: tosa.add +func.func @dont_canonicalize_tile_multi_use(%arg0: tensor<1x56x56x96xf32>, %arg1: tensor<1x56x56x1xf32>) -> (tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32>) { + %shape = tosa.const_shape {values = dense<[1, 1, 1, 96]> : tensor<4xindex>} : () -> !tosa.shape<4> + %tile = tosa.tile %arg1, %shape : (tensor<1x56x56x1xf32>, !tosa.shape<4>) -> tensor<1x56x56x96xf32> + %sub = tosa.sub %arg0, %tile : (tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32>) -> tensor<1x56x56x96xf32> + %add = tosa.add %arg0, %tile : (tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32>) -> tensor<1x56x56x96xf32> + return %sub, %add : tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_unary_elementwise +// CHECK: tosa.tile +// CHECK: tosa.abs +func.func @dont_canonicalize_tile_unary_elementwise(%arg0: tensor<2x1xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %abs = tosa.abs %tile : (tensor<2x4xf32>) -> tensor<2x4xf32> + return %abs : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_used_as_mul_shift +// CHECK: tosa.tile +// CHECK: tosa.mul +func.func @dont_canonicalize_tile_used_as_mul_shift(%lhs: tensor<1xf32>, %rhs: tensor<1xf32>, %shift: tensor) -> tensor<1xf32> { + %multiples = tosa.const_shape {values = dense<[1]> : tensor<1xindex>} : () -> !tosa.shape<1> + %shift_static = tosa.tile %shift, %multiples : (tensor, !tosa.shape<1>) -> tensor<1xi8> + %mul = tosa.mul %lhs, %rhs, %shift_static : (tensor<1xf32>, tensor<1xf32>, tensor<1xi8>) -> tensor<1xf32> + return %mul : tensor<1xf32> +} + +// ----- + // CHECK-LABEL: test_single_concat // CHECK: %[[VAL_1:.*]] = tosa.concat %arg0, %arg0 {axis = 1 : i32} : (tensor<1x1x7x7xf32>, tensor<1x1x7x7xf32>) -> tensor<1x2x7x7xf32> // CHECK: return %[[VAL_1]] : tensor<1x2x7x7xf32> diff --git a/mlir/test/Dialect/Tosa/tosa-reduce-transposes.mlir b/mlir/test/Dialect/Tosa/tosa-reduce-transposes.mlir index 0ad3068011f7f..46e4f504af0ec 100644 --- a/mlir/test/Dialect/Tosa/tosa-reduce-transposes.mlir +++ b/mlir/test/Dialect/Tosa/tosa-reduce-transposes.mlir @@ -597,3 +597,21 @@ func.func @test_unimplemented_static_diverges_to_one_nullifying_one_non_nullifyi %result = tosa.transpose %add {perms = array}: (tensor<1x3x4x2xi32>) -> tensor<1x2x3x4xi32> return %result : tensor<1x2x3x4xi32> } + +// CHECK-LABEL: @test_transpose_bool +// CHECK: %{{.*}} = "tosa.const"() +// CHECK-SAME{LITERAL}: dense<[[true, false], [false, false], [false, true]]> +func.func @test_transpose_bool() -> tensor<3x2xi1> { + %0 = "tosa.const"() <{values = dense<[[true, false, false], [false, false, true]]> : tensor<2x3xi1>}> : () -> tensor<2x3xi1> + %1 = tosa.transpose %0 {perms = array} : (tensor<2x3xi1>) -> tensor<3x2xi1> + return %1 : tensor<3x2xi1> +} + +// CHECK-LABEL: @test_transpose_i4 +// CHECK: %{{.*}} = "tosa.const"() +// CHECK-SAME{LITERAL}: dense<[[1, 4], [2, 5], [3, 6]]> +func.func @test_transpose_i4() -> tensor<3x2xi4> { + %0 = "tosa.const"() <{values = dense<[[1, 2, 3], [4, 5, 6]]> : tensor<2x3xi4>}> : () -> tensor<2x3xi4> + %1 = tosa.transpose %0 {perms = array} : (tensor<2x3xi4>) -> tensor<3x2xi4> + return %1 : tensor<3x2xi4> +} \ No newline at end of file diff --git a/mlir/test/Dialect/XeGPU/propagate-layout-inst-data.mlir b/mlir/test/Dialect/XeGPU/propagate-layout-inst-data.mlir index 515c59db72819..c72e917b6fafa 100644 --- a/mlir/test/Dialect/XeGPU/propagate-layout-inst-data.mlir +++ b/mlir/test/Dialect/XeGPU/propagate-layout-inst-data.mlir @@ -242,7 +242,7 @@ gpu.module @test { // CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense : vector<256xi1> // CHECK: %[[STEP:.*]] = vector.step {layout_result_0 = #xegpu.layout} : vector<256xindex> // CHECK: %[[LOAD:.*]] = xegpu.load %arg0[%[[STEP]]], %[[CST]] <{layout = #xegpu.layout}> : memref<256xf16>, vector<256xindex>, vector<256xi1> -> vector<256xf16> -// CHECK: %[[CAST_0:.*]] = vector.shape_cast %[[LOAD]] {layout_result_0 = #xegpu.layout} : vector<256xf16> to vector<2x4x32xf16> +// CHECK: %[[CAST_0:.*]] = vector.shape_cast %[[LOAD]] {layout_result_0 = #xegpu.layout} : vector<256xf16> to vector<2x4x32xf16> // CHECK: %[[CAST_1:.*]] = vector.shape_cast %[[CAST_0]] {layout_result_0 = #xegpu.layout} : vector<2x4x32xf16> to vector<1x256xf16> // CHECK: %[[CAST_2:.*]] = vector.shape_cast %[[CAST_1]] {layout_result_0 = #xegpu.layout} : vector<1x256xf16> to vector<256xf16> // CHECK: xegpu.store %[[CAST_2]], %arg1[%[[STEP]]], %[[CST]] <{layout = #xegpu.layout}> : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> @@ -453,21 +453,11 @@ func.func @dpas_mx_f4e2m1(%arg0: memref<16x1024xf4E2M1FN>, %arg1: memref<1024x32 } // ----- -// shape_cast that collapses all src dims into a single innermost dst dim. -// Consumer carries inst_data + lane_layout=[..,subgroupSize] + lane_data=[..,1] -// (the canonical inst-level anchor for this code path). -// Distribution is always outer-to-inner to make sure larger contiguous chunks -// are given to each compute unit first. -// srcShape=[8, 16, 32], resShape=[4096], consumer inst_data=[32], -// lane_layout=[16], lane_data=[1] -// lane_layout outer-to-inner: dim0 take=min(16,8)=8 (rem=2); -// dim1 take=min(2,16)=2 (rem=1) -> [8, 2, 1]. -// lane_data innermost-first: total=1 -> [1, 1, 1]. -// inst_data: laneAtom=16, seed [8, 2, 1]; remaining=32/16=2 spreads -// innermost-first: dim2 cap=32/1=32, take=2 -> inst_data[2]=2 -> [8, 2, 2]. +// shape_cast collapse [8, 16, 32] -> [4096]: lane/inst factors fill the fast +// innermost dim first. gpu.module @test { // CHECK-LABEL: func.func @vector_shape_cast_collapse_innermost( -// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<8x16x32xf16> +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<8x16x32xf16> // CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<8x16x32xf16> to vector<4096xf16> func.func @vector_shape_cast_collapse_innermost(%arg0: memref<4096xf16>) { %cst_v = arith.constant dense<0.000000e+00> : vector<8x16x32xf16> @@ -480,19 +470,11 @@ func.func @vector_shape_cast_collapse_innermost(%arg0: memref<4096xf16>) { } // ----- -// shape_cast collapse where the outermost src dim is too small to absorb the -// full lane_layout, so it spills inward across multiple src dims. -// srcShape=[2, 8, 32], resShape=[512], consumer inst_data=[64], -// lane_layout=[16], lane_data=[2] -// lane_layout outer-to-inner: dim0 take=min(16,2)=2 (rem=8); -// dim1 take=min(8,8)=8 (rem=1) -> [2, 8, 1]. -// lane_data innermost-first: total=2; dim2 cap=32/1=32, take=2 -> [1, 1, 2]. -// inst_data: laneAtom=16*2=32, seed [2*1, 8*1, 1*2] = [2, 8, 2]; -// remaining=64/32=2 spreads innermost-first: dim2 cap=32/2=16, take=2 -// -> inst_data[2] *= 2 -> [2, 8, 4]. +// shape_cast collapse [2, 8, 32] -> [512]: the innermost src dim absorbs the +// full lane distribution, leaving the remaining inst_data factor for dim 1. gpu.module @test { // CHECK-LABEL: func.func @vector_shape_cast_collapse_lane_layout_spill_inward( -// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x8x32xf16> +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x8x32xf16> // CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<2x8x32xf16> to vector<512xf16> func.func @vector_shape_cast_collapse_lane_layout_spill_inward(%arg0: memref<512xf16>) { %cst_v = arith.constant dense<0.000000e+00> : vector<2x8x32xf16> @@ -505,20 +487,11 @@ func.func @vector_shape_cast_collapse_lane_layout_spill_inward(%arg0: memref<512 } // ----- -// shape_cast collapse with multiple non-trivial groups: every dst dim -// collapses >=2 src dims, exercising the general matchDimCollapse path. -// srcShape=[2, 4, 8, 16], resShape=[8, 128], consumer inst_data=[1, 16], -// lane_layout=[1, 16], lane_data=[1, 1] -// - dst[0]=8 collapses src[0, 1]: lane_layout=1, lane_data=1, inst_data=1 -// -> [1, 1, _, _] for all three. -// - dst[1]=128 collapses src[2, 3]: lane_layout outer-to-inner over [2, 3]: -// dim2 take=min(16, 8)=8 (rem=2); dim3 take=min(2, 16)=2 (rem=1) -// -> [_, _, 8, 2]; lane_data=1 -> [_, _, 1, 1]; inst_data laneAtom=16, -// seed [_, _, 8*1, 2*1] = [_, _, 8, 2]; remaining=16/16=1 -> done -// -> inst_data=[_, _, 8, 2]. +// shape_cast collapse [2, 4, 8, 16] -> [8, 128]: multiple non-trivial groups, +// exercising the general matchDimCollapse path. gpu.module @test { // CHECK-LABEL: func.func @vector_shape_cast_collapse_multi_groups( -// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x4x8x16xf16> +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x4x8x16xf16> // CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<2x4x8x16xf16> to vector<8x128xf16> func.func @vector_shape_cast_collapse_multi_groups(%arg0: memref<8x128xf16>) { %cst_v = arith.constant dense<0.000000e+00> : vector<2x4x8x16xf16> @@ -529,6 +502,24 @@ func.func @vector_shape_cast_collapse_multi_groups(%arg0: memref<8x128xf16>) { } } +// ----- +// broadcast feeding a shape_cast collapse [8, 32, 32] -> [256, 32]: lanes and +// lane_data of the collapsed dim wrap around onto the fast innermost dim. +gpu.module @test { +// CHECK-LABEL: gpu.func @shape_cast_collapse_lane_layout( +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} {{.*}} : vector<8x1x32xf8E8M0FNU> +// CHECK: %[[BC:.*]] = vector.broadcast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<8x1x32xf8E8M0FNU> to vector<8x32x32xf8E8M0FNU> +// CHECK: %[[CAST:.*]] = vector.shape_cast %[[BC]] {layout_result_0 = #xegpu.layout} : vector<8x32x32xf8E8M0FNU> to vector<256x32xf8E8M0FNU> + gpu.func @shape_cast_collapse_lane_layout(%dst: memref<256x32xf8E8M0FNU>) kernel { + %cst = arith.constant dense<0.000000e+00> : vector<8x1x32xf8E8M0FNU> + %bc = vector.broadcast %cst : vector<8x1x32xf8E8M0FNU> to vector<8x32x32xf8E8M0FNU> + %sc = vector.shape_cast %bc : vector<8x32x32xf8E8M0FNU> to vector<256x32xf8E8M0FNU> + %tdesc = xegpu.create_nd_tdesc %dst : memref<256x32xf8E8M0FNU> -> !xegpu.tensor_desc<256x32xf8E8M0FNU> + xegpu.store_nd %sc, %tdesc[0, 0] <{layout = #xegpu.layout}> : vector<256x32xf8E8M0FNU>, !xegpu.tensor_desc<256x32xf8E8M0FNU> + gpu.return + } +} + // ----- // completeBlockStoreLaneLayoutFromInstData: user supplies only inst_data on a // store_nd; lane_layout / lane_data are completed from it (data sink, no diff --git a/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir b/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir index 4c6353e45cfbe..fa00c1d894d8f 100644 --- a/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir +++ b/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir @@ -579,7 +579,7 @@ gpu.module @test { // ----- gpu.module @test { // CHECK-LABEL: gpu.func @shape_cast_collapse_replicated( -// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<16x8x8xf16> +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<16x8x8xf16> // CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<16x8x8xf16> to vector<16x64xf16> gpu.func @shape_cast_collapse_replicated(%dst: memref<16x64xf16>) kernel { %cst = arith.constant dense<0.000000e+00> : vector<16x8x8xf16> @@ -590,6 +590,70 @@ gpu.module @test { } } +// ----- +// shape_cast collapse [2, 16] -> [32] with sg_layout=[4], sg_data=[4]: +// the 4 subgroups wrap around onto the fast innermost dim. +gpu.module @test { +// CHECK-LABEL: gpu.func @shape_cast_collapse_sg_wraparound( +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x16xf16> +// CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<2x16xf16> to vector<32xf16> + gpu.func @shape_cast_collapse_sg_wraparound(%dst: memref<32xf16>) kernel { + %cst = arith.constant dense<0.000000e+00> : vector<2x16xf16> + %0 = vector.shape_cast %cst : vector<2x16xf16> to vector<32xf16> + %mask = arith.constant dense : vector<32xi1> + %offsets = vector.step : vector<32xindex> + xegpu.store %0, %dst[%offsets], %mask <{layout = #xegpu.layout}> : vector<32xf16>, memref<32xf16>, vector<32xindex>, vector<32xi1> + gpu.return + } +} + +// ----- +gpu.module @test { + // Self-derived sg layout: 256 threads / 16 = 16 subgroups, sg_data = 16. + // CHECK-LABEL: store_scatter + gpu.func @store_scatter(%dest: memref<256xf16>) kernel attributes {known_block_size = array} { + %val = arith.constant dense<25.5> : vector<256xf16> + %offset = arith.constant dense<0> : vector<256xindex> + %mask = arith.constant dense<1> : vector<256xi1> + // CHECK: xegpu.store %{{.*}}, %{{.*}}[%{{.*}}], %{{.*}} <{chunk_size = 1 : i64, l1_hint = #xegpu.cache_hint, layout = #xegpu.layout}> + // CHECK-SAME: : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> + xegpu.store %val, %dest[%offset], %mask {chunk_size = 1, l1_hint = #xegpu.cache_hint} + : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> + gpu.return + } +} + +// ----- +gpu.module @test { + // Self-derived sg layout: 512 threads / 16 = 32 subgroups, most balanced + // factorization [4, 8] over [64, 128] -> sg_data [16, 16]. + // CHECK-LABEL: store_matrix + gpu.func @store_matrix(%mem: !xegpu.mem_desc<64x128xf16>, %val: vector<64x128xf16>) kernel attributes {known_block_size = array} { + %c0 = arith.constant 0 : index + // CHECK: xegpu.store_matrix %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] <{layout = #xegpu.layout}> + // CHECK-SAME: : vector<64x128xf16>, !xegpu.mem_desc<64x128xf16>, index, index + xegpu.store_matrix %val, %mem[%c0, %c0] : vector<64x128xf16>, !xegpu.mem_desc<64x128xf16>, index, index + gpu.return + } +} + +// ----- +gpu.module @test { + // No valid sg layout: 32 subgroups over 256 elements forces sg_data = 8 < + // 16-lane tile, so every candidate is rejected; layout is left unassigned. + // CHECK-LABEL: store_scatter_no_valid_sg_layout + gpu.func @store_scatter_no_valid_sg_layout(%dest: memref<256xf16>) kernel attributes {known_block_size = array} { + %val = arith.constant dense<25.5> : vector<256xf16> + %offset = arith.constant dense<0> : vector<256xindex> + %mask = arith.constant dense<1> : vector<256xi1> + // CHECK: xegpu.store %{{.*}}, %{{.*}}[%{{.*}}], %{{.*}} <{chunk_size = 1 : i64, l1_hint = #xegpu.cache_hint}> + // CHECK-SAME: : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> + xegpu.store %val, %dest[%offset], %mask {chunk_size = 1, l1_hint = #xegpu.cache_hint} + : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> + gpu.return + } +} + // ----- gpu.module @test { // CHECK-LABEL: gpu.func @transpose_3d_order_remap( diff --git a/mlir/test/Dialect/XeGPU/propagate-layout.mlir b/mlir/test/Dialect/XeGPU/propagate-layout.mlir index 1a741ba21e128..1311a6a588dbf 100644 --- a/mlir/test/Dialect/XeGPU/propagate-layout.mlir +++ b/mlir/test/Dialect/XeGPU/propagate-layout.mlir @@ -808,7 +808,7 @@ gpu.module @test { // CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense : vector<256xi1> // CHECK: %[[STEP:.*]] = vector.step {layout_result_0 = #xegpu.layout} : vector<256xindex> // CHECK: %[[LOAD:.*]] = xegpu.load %arg0[%[[STEP]]], %[[CST]] <{layout = #xegpu.layout}> : memref<256xf16>, vector<256xindex>, vector<256xi1> -> vector<256xf16> -// CHECK: %[[CAST_0:.*]] = vector.shape_cast %[[LOAD]] {layout_result_0 = #xegpu.layout} : vector<256xf16> to vector<2x4x32xf16> +// CHECK: %[[CAST_0:.*]] = vector.shape_cast %[[LOAD]] {layout_result_0 = #xegpu.layout} : vector<256xf16> to vector<2x4x32xf16> // CHECK: %[[CAST_1:.*]] = vector.shape_cast %[[CAST_0]] {layout_result_0 = #xegpu.layout} : vector<2x4x32xf16> to vector<1x256xf16> // CHECK: %[[CAST_2:.*]] = vector.shape_cast %[[CAST_1]] {layout_result_0 = #xegpu.layout} : vector<1x256xf16> to vector<256xf16> // CHECK: xegpu.store %[[CAST_2]], %arg1[%[[STEP]]], %[[CST]] <{layout = #xegpu.layout}> : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> diff --git a/mlir/test/Target/Cpp/expressions.mlir b/mlir/test/Target/Cpp/expressions.mlir index d447f9a38f3d3..43e43cda49477 100644 --- a/mlir/test/Target/Cpp/expressions.mlir +++ b/mlir/test/Target/Cpp/expressions.mlir @@ -89,11 +89,14 @@ func.func @do_not_inline(%arg0: i32, %arg1: i32, %arg2 : i32) -> i32 { } // CPP-DEFAULT: float parentheses_for_low_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) { -// CPP-DEFAULT-NEXT: return (float) (([[VAL_1]] + [[VAL_2]]) * [[VAL_3]]); +// CPP-DEFAULT-NEXT: float [[VAL_4:v[0-9]+]] = (float) (([[VAL_1]] + [[VAL_2]]) * [[VAL_3]]); +// CPP-DEFAULT-NEXT: return [[VAL_4]]; // CPP-DEFAULT-NEXT: } // CPP-DECLTOP: float parentheses_for_low_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) { -// CPP-DECLTOP-NEXT: return (float) (([[VAL_1]] + [[VAL_2]]) * [[VAL_3]]); +// CPP-DECLTOP-NEXT: float [[VAL_4:v[0-9]+]]; +// CPP-DECLTOP-NEXT: [[VAL_4]] = (float) (([[VAL_1]] + [[VAL_2]]) * [[VAL_3]]); +// CPP-DECLTOP-NEXT: return [[VAL_4]]; // CPP-DECLTOP-NEXT: } func.func @parentheses_for_low_precedence(%arg0: i32, %arg1: i32, %arg2: i32) -> f32 { @@ -106,6 +109,41 @@ func.func @parentheses_for_low_precedence(%arg0: i32, %arg1: i32, %arg2: i32) -> return %e : f32 } +// CPP-DEFAULT: float inline_cast_pure(int32_t [[VAL_1:v[0-9]+]]) { +// CPP-DEFAULT-NEXT: return (float) [[VAL_1]]; +// CPP-DEFAULT-NEXT: } + +// CPP-DECLTOP: float inline_cast_pure(int32_t [[VAL_1:v[0-9]+]]) { +// CPP-DECLTOP-NEXT: return (float) [[VAL_1]]; +// CPP-DECLTOP-NEXT: } + +func.func @inline_cast_pure(%arg0: i32) -> f32 { + %0 = emitc.expression %arg0 : (i32) -> f32 { + %1 = cast %arg0 {pure} : i32 to f32 + yield %1 : f32 + } + return %0 : f32 +} + +// CPP-DEFAULT: float do_not_inline_cast_without_pure(int32_t [[VAL_1:v[0-9]+]]) { +// CPP-DEFAULT-NEXT: float [[VAL_2:v[0-9]+]] = (float) [[VAL_1]]; +// CPP-DEFAULT-NEXT: return [[VAL_2]]; +// CPP-DEFAULT-NEXT: } + +// CPP-DECLTOP: float do_not_inline_cast_without_pure(int32_t [[VAL_1:v[0-9]+]]) { +// CPP-DECLTOP-NEXT: float [[VAL_2:v[0-9]+]]; +// CPP-DECLTOP-NEXT: [[VAL_2]] = (float) [[VAL_1]]; +// CPP-DECLTOP-NEXT: return [[VAL_2]]; +// CPP-DECLTOP-NEXT: } + +func.func @do_not_inline_cast_without_pure(%arg0: i32) -> f32 { + %0 = emitc.expression %arg0 : (i32) -> f32 { + %1 = cast %arg0 : i32 to f32 + yield %1 : f32 + } + return %0 : f32 +} + // CPP-DEFAULT: int32_t parentheses_for_same_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) { // CPP-DEFAULT-NEXT: return [[VAL_3]] / ([[VAL_1]] * [[VAL_2]]); // CPP-DEFAULT-NEXT: } diff --git a/mlir/test/Transforms/remove-dead-values.mlir b/mlir/test/Transforms/remove-dead-values.mlir index 64088ce15cd48..390a448060b7f 100644 --- a/mlir/test/Transforms/remove-dead-values.mlir +++ b/mlir/test/Transforms/remove-dead-values.mlir @@ -624,6 +624,33 @@ module @return_void_with_unused_argument { // ----- +// CHECK-LABEL: func.func private @keep_region_branch_operands_valid() { +func.func private @keep_region_branch_operands_valid(%arg0: memref) { + %false = arith.constant false + %cst = arith.constant 2.000000e+00 : f64 + %0 = memref.load %arg0[] {name = "caller"} : memref + memref.store %cst, %arg0[] {name = "callee"} : memref + // CHECK: %[[COND:.*]] = ub.poison : i1 + // CHECK: scf.if %[[COND]] + // CHECK: %[[YIELD0:.*]] = ub.poison : memref + // CHECK: scf.yield %[[YIELD0]] : memref + // CHECK: %[[YIELD1:.*]] = ub.poison : memref + // CHECK: scf.yield %[[YIELD1]] : memref + %1 = scf.if %false -> (memref) { + scf.yield %arg0 : memref + } else { + %2 = bufferization.clone %arg0 : memref to memref + scf.yield %2 : memref + } + %true = arith.constant true + %base_buffer, %offset = memref.extract_strided_metadata %arg0 : memref -> memref, index + %base_buffer_0, %offset_1 = memref.extract_strided_metadata %1 : memref -> memref, index + bufferization.dealloc (%base_buffer, %base_buffer_0 : memref, memref) if (%false, %true) + return +} + +// ----- + // CHECK-LABEL: module @dynamically_unreachable module @dynamically_unreachable { func.func @dynamically_unreachable() { diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp index e6ceeea5331d1..f1caee0c4c1e2 100644 --- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp +++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp @@ -126,8 +126,8 @@ static hsa_status_t iterate(IterFuncTy Func, IterFuncArgTy FuncArg, /// use this function directly but the specialized ones below instead. template -static hsa_status_t iterate(IterFuncTy Func, IterFuncArgTy FuncArg, - CallbackTy Cb) { +[[maybe_unused]] static hsa_status_t +iterate(IterFuncTy Func, IterFuncArgTy FuncArg, CallbackTy Cb) { auto L = [](Elem1Ty Elem1, Elem2Ty Elem2, void *Data) -> hsa_status_t { CallbackTy *Unwrapped = static_cast(Data); return (*Unwrapped)(Elem1, Elem2); diff --git a/offload/plugins-nextgen/common/include/OffloadError.h b/offload/plugins-nextgen/common/include/OffloadError.h index f2a56d2c41117..3d0ceb400c99c 100644 --- a/offload/plugins-nextgen/common/include/OffloadError.h +++ b/offload/plugins-nextgen/common/include/OffloadError.h @@ -49,8 +49,8 @@ class OffloadError : public llvm::ErrorInfo { /// Create an Offload error. template -static llvm::Error createOffloadError(error::ErrorCode Code, const char *ErrFmt, - ArgsTy... Args) { +[[maybe_unused]] static llvm::Error +createOffloadError(error::ErrorCode Code, const char *ErrFmt, ArgsTy... Args) { std::string Buffer; llvm::raw_string_ostream(Buffer) << llvm::format(ErrFmt, Args...); return llvm::make_error(Code, Buffer); diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h index 400605763b365..2a23d319fff49 100644 --- a/offload/plugins-nextgen/common/include/PluginInterface.h +++ b/offload/plugins-nextgen/common/include/PluginInterface.h @@ -98,7 +98,8 @@ inline Error error(error::ErrorCode Code, Error &&OtherError, /// the plugin-specific code. /// TODO: Refactor this, must be defined individually by each plugin. template -static Error check(int32_t ErrorCode, const char *ErrFmt, ArgsTy... Args); +[[maybe_unused]] static Error check(int32_t ErrorCode, const char *ErrFmt, + ArgsTy... Args); } // namespace Plugin /// Class that wraps the __tgt_async_info to simply its usage. In case the diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp index 505494095a10a..a5d4ffd003fd7 100644 --- a/offload/plugins-nextgen/host/src/rtl.cpp +++ b/offload/plugins-nextgen/host/src/rtl.cpp @@ -558,7 +558,8 @@ struct GenELF64PluginTy final : public GenericPluginTy { }; template -static Error Plugin::check(int32_t Code, const char *ErrMsg, ArgsTy... Args) { +[[maybe_unused]] static Error Plugin::check(int32_t Code, const char *ErrMsg, + ArgsTy... Args) { if (Code == 0) return Plugin::success(); diff --git a/offload/test/lit.cfg b/offload/test/lit.cfg index 03f3db08a2def..95f33caffdb6f 100644 --- a/offload/test/lit.cfg +++ b/offload/test/lit.cfg @@ -144,7 +144,7 @@ profdata_path = os.path.join(config.bin_llvm_tools_dir, "llvm-profdata") target = remove_suffix_if_present(config.libomptarget_current_target) has_profile_rt = True has_flang_rt = True -if target.startswith('amdgcn') or target.startswith('nvptx'): +if target.startswith('amdgpu') or target.startswith('nvptx'): has_profile_rt = bool(glob.glob(os.path.join( config.llvm_lib_directory, 'clang', '*', 'lib', target, 'libclang_rt.profile.a'))) @@ -171,7 +171,7 @@ if config.libomptarget_current_target.startswith('nvptx'): except ValueError: # If the architecture is invalid, assume it is supported. supports_unified_shared_memory = True -elif config.libomptarget_current_target.startswith('amdgcn'): +elif config.libomptarget_current_target.startswith('amdgpu'): # amdgpu_test_arch contains a list of AMD GPUs in the system # only check the first one assuming that we will run the test on it. if (config.amdgpu_test_arch.startswith("gfx90a") or @@ -231,7 +231,7 @@ host_targets = [ if config.libomptarget_current_target.startswith('nvptx'): config.available_features.add('gpu') config.available_features.add('nvidiagpu') -if config.libomptarget_current_target.startswith('amdgcn'): +if config.libomptarget_current_target.startswith('amdgpu'): config.available_features.add('gpu') config.available_features.add('amdgpu') config.environment['HSA_DISABLE_COREDUMP_ON_EXCEPTION'] = '1' diff --git a/openmp/runtime/src/ompt-general.cpp b/openmp/runtime/src/ompt-general.cpp index a708a8d76fcf4..1682f7e74bd14 100644 --- a/openmp/runtime/src/ompt-general.cpp +++ b/openmp/runtime/src/ompt-general.cpp @@ -60,6 +60,12 @@ static FILE *verbose_file; static int verbose_init; +#if defined(__GLIBC__) +#define OMPT_GETENV secure_getenv +#else +#define OMPT_GETENV getenv +#endif + /***************************************************************************** * types ****************************************************************************/ @@ -281,7 +287,7 @@ ompt_try_start_tool(unsigned int omp_version, const char *runtime_version) { // Try tool-libraries-var ICV OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed.\n"); - const char *tool_libs = getenv("OMP_TOOL_LIBRARIES"); + const char *tool_libs = OMPT_GETENV("OMP_TOOL_LIBRARIES"); if (tool_libs) { OMPT_VERBOSE_INIT_PRINT("Searching tool libraries...\n"); OMPT_VERBOSE_INIT_PRINT("OMP_TOOL_LIBRARIES = %s\n", tool_libs); diff --git a/orc-rt/docs/CodingConventions.md b/orc-rt/docs/CodingConventions.md new file mode 100644 index 0000000000000..80dab8ad2fd2d --- /dev/null +++ b/orc-rt/docs/CodingConventions.md @@ -0,0 +1,61 @@ +# ORC-RT Coding Conventions + +## Overview + +ORC-RT is part of the LLVM project and generally follows the +[LLVM Coding Standards](https://llvm.org/docs/CodingStandards.html), including +LLVM's naming conventions for C++ code: `PascalCase` for types, values, and +variables, and `camelBack` (lower-camelCase) for functions. + +This document records conventions that are specific to ORC-RT, or that need +restating because they are not obvious from the LLVM standards alone. Where this +document is silent, follow the LLVM Coding Standards. + +## C API naming + +The C API headers (under `include/orc-rt-c/`) cannot use C++ namespaces, so +namespacing is expressed through symbol-name prefixes, while the *casing* of +each name still follows the LLVM naming conventions used elsewhere in the +project. + +The rules are: + +- **`orc_rt_` is the top-level C namespace.** Every public C symbol begins with + it. +- **Nested namespaces are additional lower-case, underscore-separated + segments.** For example, `orc_rt_log_` is the nested namespace for the logging + API. +- **Types, values, and variables are `PascalCase`** (as in LLVM), appended to + their namespace prefix. +- **Functions are `camelBack`** (as in LLVM), appended to their namespace + prefix. +- **Enumerators are `PascalCase` values, scoped by prefixing them with their + enclosing type's name** (C has no scoped enums), joined with an underscore. +- **Macros are `UPPER_CASE`**, as in LLVM and C generally. + +A PascalCase type name may itself act as a scope for its "member" functions, +exactly like a nested namespace does; the two are indistinguishable in the +flattened C name, and both are spelled with a trailing underscore. + +### Examples + +| Symbol | Kind | +|-------------------------------|----------| +| `orc_rt_ErrorRef` | type | +| `orc_rt_Error_getTypeId` | function | +| `orc_rt_StringError_create` | function | +| `orc_rt_log_Category` | type | +| `orc_rt_log_Category_General` | value | +| `orc_rt_log_formatCheck` | function | +| `ORC_RT_LOG` | macro | + +Reading these: `orc_rt_Error_getTypeId` is the `getTypeId` function scoped to +the `Error` type; `orc_rt_log_formatCheck` is the `formatCheck` function in the +`log` namespace; and `orc_rt_log_Category_General` is the `General` value of the +`Category` type in the `log` namespace. + +## C++ code + +C++ code follows the LLVM Coding Standards directly: symbols live in real +namespaces (e.g. `orc_rt`), types/values/variables are `PascalCase`, functions +are `camelBack`, and macros are `UPPER_CASE`. diff --git a/orc-rt/docs/index.md b/orc-rt/docs/index.md index 56f9bb3829c17..b5fa45d77403e 100644 --- a/orc-rt/docs/index.md +++ b/orc-rt/docs/index.md @@ -9,6 +9,7 @@ The ORC runtime provides executor-side support code for the LLVM ORC APIs. :titlesonly: Building-orc-rt + CodingConventions ``` ### Current Status diff --git a/orc-rt/include/orc-rt-c/Logging.h b/orc-rt/include/orc-rt-c/Logging.h index 5b1ec86ec2ab4..26da505bbb491 100644 --- a/orc-rt/include/orc-rt-c/Logging.h +++ b/orc-rt/include/orc-rt-c/Logging.h @@ -14,7 +14,7 @@ |* ORC_RT_LOG(Level, Category, Fmt, ...) *| |* *| |* where Level is one of Error, Warning, Info, Debug; Category is one of the *| -|* orc_rt_LogCategory tokens (without the leading "orc_rt_LogCategory_"); *| +|* orc_rt_log_Category tokens (without the leading "orc_rt_log_Category_"); *| |* and Fmt, ... are a printf-style format string and arguments, e.g. *| |* *| |* ORC_RT_LOG(Error, General, "failed to map %zu bytes", Size); *| @@ -50,17 +50,49 @@ ORC_RT_C_EXTERN_C_BEGIN * categories here as call sites require them. */ typedef enum { - orc_rt_LogCategory_General, -} orc_rt_LogCategory; + orc_rt_log_Category_General, + + /* + * Count is the number of defined categories; it is not itself a valid + * category. + */ + orc_rt_log_Category_Count +} orc_rt_log_Category; + +/** + * Logging levels are integers. Valid values are ORC_RT_LOG_LEVEL_DEBUG, + * ORC_RT_LOG_LEVEL_INFO, ORC_RT_LOG_LEVEL_WARNING, ORC_RT_LOG_LEVEL_ERROR, and + * ORC_RT_LOG_LEVEL_OFF. + */ +typedef int orc_rt_log_Level; + +/** + * Returns the display name for the given category, or null if the category is + * unrecognized. + */ +const char * +orc_rt_log_Category_getName(orc_rt_log_Category Cat) ORC_RT_C_NOTHROW; + +/** + * Returns the display name for the given log level, or null if the log level + * is unrecognized. + */ +const char *orc_rt_log_Level_getName(orc_rt_log_Level L) ORC_RT_C_NOTHROW; + +/** + * Returns the level corresponding to the given level name, or -1 if the level + * name is unrecognized. + * + * Comparison is case-insensitive. + */ +orc_rt_log_Level orc_rt_log_Level_parse(const char *Str) ORC_RT_C_NOTHROW; /** * Declared but never defined: referenced only in unevaluated (sizeof) contexts * to type-check a printf-style format string against its arguments without * evaluating them or emitting any code. */ -int orc_rt_log_format_check(const char *Fmt, ...) ORC_RT_C_FORMAT_PRINTF(1, 2); - -ORC_RT_C_EXTERN_C_END +int orc_rt_log_formatCheck(const char *Fmt, ...) ORC_RT_C_FORMAT_PRINTF(1, 2); /* * A disabled log site. Validates the category token, format string, and @@ -68,7 +100,7 @@ ORC_RT_C_EXTERN_C_END * both operands sit in unevaluated sizeof contexts. */ #define ORC_RT_LOG_DISABLED(Category, ...) \ - ((void)sizeof(Category), (void)sizeof(orc_rt_log_format_check(__VA_ARGS__))) + ((void)sizeof(Category), (void)sizeof(orc_rt_log_formatCheck(__VA_ARGS__))) /* * ORC_RT_LOG dispatches on the level token to a per-level macro, which each @@ -78,7 +110,7 @@ ORC_RT_C_EXTERN_C_END * needed. */ #define ORC_RT_LOG(Level, Category, ...) \ - ORC_RT_LOG_##Level(orc_rt_LogCategory_##Category, __VA_ARGS__) + ORC_RT_LOG_##Level(orc_rt_log_Category_##Category, __VA_ARGS__) #if ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_NONE @@ -100,4 +132,6 @@ ORC_RT_C_EXTERN_C_END #error "Unknown ORC_RT_LOG_BACKEND." #endif +ORC_RT_C_EXTERN_C_END + #endif /* ORC_RT_C_LOGGING_H */ diff --git a/orc-rt/include/orc-rt-c/config.h.in b/orc-rt/include/orc-rt-c/config.h.in index f5eef7fa4ce55..c4ff9a0fb4cd2 100644 --- a/orc-rt/include/orc-rt-c/config.h.in +++ b/orc-rt/include/orc-rt-c/config.h.in @@ -21,6 +21,8 @@ #define ORC_RT_LOG_LEVEL_INFO 1 #define ORC_RT_LOG_LEVEL_WARNING 2 #define ORC_RT_LOG_LEVEL_ERROR 3 +#define ORC_RT_LOG_LEVEL_OFF 4 +#define ORC_RT_LOG_LEVEL_COUNT (ORC_RT_LOG_LEVEL_OFF + 1) /* Fail loudly if CMake derived a symbol that isn't defined above. */ #ifndef @ORC_RT_LOG_LEVEL_VALUE@ #error "Invalid ORC_RT_LOG_LEVEL" diff --git a/orc-rt/include/orc-rt-utils/CommandLine.h b/orc-rt/include/orc-rt-utils/CommandLine.h new file mode 100644 index 0000000000000..3582d88bb7df6 --- /dev/null +++ b/orc-rt/include/orc-rt-utils/CommandLine.h @@ -0,0 +1,256 @@ +//===- CommandLine.h ------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Simple orc-rt command-line parser. Supports flags, values and positionals. +// All storage owned by caller. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "orc-rt/Error.h" + +namespace orc_rt { +namespace detail { + +template inline std::optional parseValue(std::string_view Str); + +template <> +inline std::optional +parseValue(std::string_view Str) { + return std::string(Str); +} + +template <> +inline std::optional +parseValue(std::string_view Str) { + return Str; +} + +template <> inline std::optional parseValue(std::string_view Str) { + if (Str.empty()) + return std::nullopt; + int Val{}; + auto Ret = std::from_chars(Str.data(), Str.data() + Str.size(), Val); + if (Ret.ec != std::errc() || Ret.ptr != Str.data() + Str.size()) + return std::nullopt; + return Val; +} + +template <> inline std::optional parseValue(std::string_view Str) { + if (Str.empty()) + return std::nullopt; + + if (Str == "1") + return true; + if (Str == "0") + return false; + + std::string Val; + std::transform( + Str.begin(), Str.end(), std::back_inserter(Val), + [](unsigned char C) { return static_cast(std::tolower(C)); }); + + if (Val == "true") + return true; + if (Val == "false") + return false; + + return std::nullopt; +} +} // namespace detail + +class CommandLineParser { +public: + enum class OptionKind { Flag, Value }; + CommandLineParser() = default; + + CommandLineParser &addFlag(std::string_view Name, std::string_view Desc, + bool DefaultVal, bool &Val, + std::optional ShortName = std::nullopt) { + return addValue(Name, Desc, DefaultVal, Val, OptionKind::Flag, + std::move(ShortName)); + } + + template + CommandLineParser &addValue(std::string_view Name, std::string_view Desc, + T DefaultVal, T &Val, + OptionKind Kind = OptionKind::Value, + std::optional ShortName = std::nullopt) { + Val = DefaultVal; + Opts.push_back({.Name = std::string(Name), + .ShortName = std::move(ShortName), + .Desc = std::string(Desc), + .Kind = Kind, + .Default = [&Val, DV = DefaultVal]() { Val = DV; }, + .FromString = [&Val, OptName = std::string(Name)]( + std::string_view S) -> orc_rt::Error { + if (auto V = detail::parseValue(S)) { + Val = *V; + return orc_rt::Error::success(); + } + return orc_rt::make_error( + std::string("Invalid value for '") + OptName + + "': '" + std::string(S) + "'"); + }}); + return *this; + } + + void printHelp(std::ostream &OS, std::string_view ProgramName) const { + OS << "Usage: " << ProgramName << " [options] [positional arguments]\n\n"; + OS << "OPTIONS:\n"; + + bool AnyShortNames = + std::any_of(Opts.begin(), Opts.end(), + [](const Option &O) { return O.ShortName.has_value(); }); + + size_t MaxWidth = 0; + for (const auto &Opt : Opts) { + size_t CurrentWidth = 2; // " " + if (AnyShortNames) + CurrentWidth += 4; // "-x, " + CurrentWidth += 2 + Opt.Name.length(); // "--name" + if (Opt.Kind == OptionKind::Value) + CurrentWidth += 8; // " " + MaxWidth = std::max(MaxWidth, CurrentWidth); + } + + for (const auto &Opt : Opts) { + std::string FlagStr = " "; + if (AnyShortNames) { + if (Opt.ShortName) { + FlagStr += "-"; + FlagStr += *Opt.ShortName; + FlagStr += ", "; + } else { + FlagStr += " "; // Pad gutter + } + } + FlagStr += "--" + Opt.Name; + if (Opt.Kind == OptionKind::Value) + FlagStr += " "; + + OS << std::left << std::setw(MaxWidth + 2) << FlagStr << Opt.Desc << "\n"; + } + } + + template orc_rt::Error parse(I Begin, I End) { + std::for_each(Opts.begin(), Opts.end(), + [](const Option &O) { O.Default(); }); + Positionals.clear(); + bool AfterDashDash = false; + if (Begin != End) + Begin++; + + for (auto It = Begin; It != End; ++It) { + std::string_view Tok(*It); + if (!AfterDashDash && Tok == "--") { + AfterDashDash = true; + continue; + } + if (!AfterDashDash && startsWith(Tok, "--")) { + std::string_view K = Tok.substr(2); + std::string_view V; + bool HasValue = false; + if (auto P = K.find('='); P != std::string_view::npos) { + V = K.substr(P + 1); + K = K.substr(0, P); + HasValue = true; + } + auto FoundOpt = findOpt(K); + if (!FoundOpt) + return orc_rt::make_error( + "Unknown option '" + std::string(Tok) + "'"); + if (auto Err = consumeValue(FoundOpt, V, HasValue, It, End)) + return Err; + } else if (!AfterDashDash && startsWith(Tok, "-") && Tok.size() > 1) { + std::string_view Group = Tok.substr(1); + for (size_t i = 0; i < Group.size(); ++i) { + auto FoundOpt = findOpt(Group[i]); + if (!FoundOpt) + return orc_rt::make_error( + std::string("Unknown short option '-") + Group[i] + "'"); + if (FoundOpt->Kind == OptionKind::Value) { + std::string_view V = Group.substr(i + 1); + bool HasValue = !V.empty(); + if (auto Err = consumeValue(FoundOpt, V, HasValue, It, End)) + return Err; + break; + } else { + if (auto Err = FoundOpt->FromString("true")) + return Err; + } + } + } else { + Positionals.emplace_back(Tok); + } + } + return orc_rt::Error::success(); + } + + orc_rt::Error parse(int argc, char **argv) { + return parse(argv, argv + argc); + } + + const std::vector &positionals() const { return Positionals; } + +private: + struct Option { + std::string Name; + std::optional ShortName; + std::string Desc; + OptionKind Kind{}; + std::function Default; + std::function FromString; + }; + + std::vector Positionals; + std::vector